From 0e787fb7f5b56b4fe87cd8ada64ae740bbca87bc Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Wed, 24 Jul 2024 19:37:05 +0900 Subject: Rename text class nt* related files to equivalent tq* Signed-off-by: Michele Calgaro --- src/tools/ntqlocale.h | 494 ---- src/tools/qfeatures.txt | 2 +- src/tools/qglobal.cpp | 2 +- src/tools/qlocale.cpp | 6322 ----------------------------------------------- src/tools/qlocale_p.h | 131 - src/tools/qt_tools.pri | 8 +- src/tools/tqlocale.cpp | 6322 +++++++++++++++++++++++++++++++++++++++++++++++ src/tools/tqlocale.h | 494 ++++ src/tools/tqlocale_p.h | 131 + src/tools/tqstring.cpp | 4 +- 10 files changed, 6955 insertions(+), 6955 deletions(-) delete mode 100644 src/tools/ntqlocale.h delete mode 100644 src/tools/qlocale.cpp delete mode 100644 src/tools/qlocale_p.h create mode 100644 src/tools/tqlocale.cpp create mode 100644 src/tools/tqlocale.h create mode 100644 src/tools/tqlocale_p.h (limited to 'src/tools') diff --git a/src/tools/ntqlocale.h b/src/tools/ntqlocale.h deleted file mode 100644 index d3a578d1c..000000000 --- a/src/tools/ntqlocale.h +++ /dev/null @@ -1,494 +0,0 @@ -/**************************************************************************** -** -** Declaration of the TQLocale class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the tools module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQLOCALE_H -#define TQLOCALE_H - -#include "tqstring.h" - -struct TQLocalePrivate; - -class TQ_EXPORT TQLocale -{ - friend class TQString; - -public: - enum Language { - C = 1, - Abkhazian = 2, - Afan = 3, - Afar = 4, - Afrikaans = 5, - Albanian = 6, - Amharic = 7, - Arabic = 8, - Armenian = 9, - Assamese = 10, - Aymara = 11, - Azerbaijani = 12, - Bashkir = 13, - Basque = 14, - Bengali = 15, - Bhutani = 16, - Bihari = 17, - Bislama = 18, - Breton = 19, - Bulgarian = 20, - Burmese = 21, - Byelorussian = 22, - Cambodian = 23, - Catalan = 24, - Chinese = 25, - Corsican = 26, - Croatian = 27, - Czech = 28, - Danish = 29, - Dutch = 30, - English = 31, - Esperanto = 32, - Estonian = 33, - Faroese = 34, - FijiLanguage = 35, - Finnish = 36, - French = 37, - Frisian = 38, - Gaelic = 39, - Galician = 40, - Georgian = 41, - German = 42, - Greek = 43, - Greenlandic = 44, - Guarani = 45, - Gujarati = 46, - Hausa = 47, - Hebrew = 48, - Hindi = 49, - Hungarian = 50, - Icelandic = 51, - Indonesian = 52, - Interlingua = 53, - Interlingue = 54, - Inuktitut = 55, - Inupiak = 56, - Irish = 57, - Italian = 58, - Japanese = 59, - Javanese = 60, - Kannada = 61, - Kashmiri = 62, - Kazakh = 63, - Kinyarwanda = 64, - Kirghiz = 65, - Korean = 66, - Kurdish = 67, - Kurundi = 68, - Laothian = 69, - Latin = 70, - Latvian = 71, - Lingala = 72, - Lithuanian = 73, - Macedonian = 74, - Malagasy = 75, - Malay = 76, - Malayalam = 77, - Maltese = 78, - Maori = 79, - Marathi = 80, - Moldavian = 81, - Mongolian = 82, - NauruLanguage = 83, - Nepali = 84, - Norwegian = 85, - Occitan = 86, - Oriya = 87, - Pashto = 88, - Persian = 89, - Polish = 90, - Portuguese = 91, - Punjabi = 92, - Quechua = 93, - RhaetoRomance = 94, - Romanian = 95, - Russian = 96, - Samoan = 97, - Sangho = 98, - Sanskrit = 99, - Serbian = 100, - SerboCroatian = 101, - Sesotho = 102, - Setswana = 103, - Shona = 104, - Sindhi = 105, - Singhalese = 106, - Siswati = 107, - Slovak = 108, - Slovenian = 109, - Somali = 110, - Spanish = 111, - Sundanese = 112, - Swahili = 113, - Swedish = 114, - Tagalog = 115, - Tajik = 116, - Tamil = 117, - Tatar = 118, - Telugu = 119, - Thai = 120, - Tibetan = 121, - Tigrinya = 122, - TongaLanguage = 123, - Tsonga = 124, - Turkish = 125, - Turkmen = 126, - Twi = 127, - Uigur = 128, - Ukrainian = 129, - Urdu = 130, - Uzbek = 131, - Vietnamese = 132, - Volapuk = 133, - Welsh = 134, - Wolof = 135, - Xhosa = 136, - Yiddish = 137, - Yoruba = 138, - Zhuang = 139, - Zulu = 140, - LastLanguage = Zulu - }; - - enum Country { - AnyCountry = 0, - Afghanistan = 1, - Albania = 2, - Algeria = 3, - AmericanSamoa = 4, - Andorra = 5, - Angola = 6, - Anguilla = 7, - Antarctica = 8, - AntiguaAndBarbuda = 9, - Argentina = 10, - Armenia = 11, - Aruba = 12, - Australia = 13, - Austria = 14, - Azerbaijan = 15, - Bahamas = 16, - Bahrain = 17, - Bangladesh = 18, - Barbados = 19, - Belarus = 20, - Belgium = 21, - Belize = 22, - Benin = 23, - Bermuda = 24, - Bhutan = 25, - Bolivia = 26, - BosniaAndHerzegowina = 27, - Botswana = 28, - BouvetIsland = 29, - Brazil = 30, - BritishIndianOceanTerritory = 31, - BruneiDarussalam = 32, - Bulgaria = 33, - BurkinaFaso = 34, - Burundi = 35, - Cambodia = 36, - Cameroon = 37, - Canada = 38, - CapeVerde = 39, - CaymanIslands = 40, - CentralAfricanRepublic = 41, - Chad = 42, - Chile = 43, - China = 44, - ChristmasIsland = 45, - CocosIslands = 46, - Colombia = 47, - Comoros = 48, - DemocraticRepublicOfCongo = 49, - PeoplesRepublicOfCongo = 50, - CookIslands = 51, - CostaRica = 52, - IvoryCoast = 53, - Croatia = 54, - Cuba = 55, - Cyprus = 56, - CzechRepublic = 57, - Denmark = 58, - Djibouti = 59, - Dominica = 60, - DominicanRepublic = 61, - EastTimor = 62, - Ecuador = 63, - Egypt = 64, - ElSalvador = 65, - EquatorialGuinea = 66, - Eritrea = 67, - Estonia = 68, - Ethiopia = 69, - FalklandIslands = 70, - FaroeIslands = 71, - FijiCountry = 72, - Finland = 73, - France = 74, - MetropolitanFrance = 75, - FrenchGuiana = 76, - FrenchPolynesia = 77, - FrenchSouthernTerritories = 78, - Gabon = 79, - Gambia = 80, - Georgia = 81, - Germany = 82, - Ghana = 83, - Gibraltar = 84, - Greece = 85, - Greenland = 86, - Grenada = 87, - Guadeloupe = 88, - Guam = 89, - Guatemala = 90, - Guinea = 91, - GuineaBissau = 92, - Guyana = 93, - Haiti = 94, - HeardAndMcDonaldIslands = 95, - Honduras = 96, - HongKong = 97, - Hungary = 98, - Iceland = 99, - India = 100, - Indonesia = 101, - Iran = 102, - Iraq = 103, - Ireland = 104, - Israel = 105, - Italy = 106, - Jamaica = 107, - Japan = 108, - Jordan = 109, - Kazakhstan = 110, - Kenya = 111, - Kiribati = 112, - DemocraticRepublicOfKorea = 113, - RepublicOfKorea = 114, - Kuwait = 115, - Kyrgyzstan = 116, - Lao = 117, - Latvia = 118, - Lebanon = 119, - Lesotho = 120, - Liberia = 121, - LibyanArabJamahiriya = 122, - Liechtenstein = 123, - Lithuania = 124, - Luxembourg = 125, - Macau = 126, - Macedonia = 127, - Madagascar = 128, - Malawi = 129, - Malaysia = 130, - Maldives = 131, - Mali = 132, - Malta = 133, - MarshallIslands = 134, - Martinique = 135, - Mauritania = 136, - Mauritius = 137, - Mayotte = 138, - Mexico = 139, - Micronesia = 140, - Moldova = 141, - Monaco = 142, - Mongolia = 143, - Montserrat = 144, - Morocco = 145, - Mozambique = 146, - Myanmar = 147, - Namibia = 148, - NauruCountry = 149, - Nepal = 150, - Netherlands = 151, - NetherlandsAntilles = 152, - NewCaledonia = 153, - NewZealand = 154, - Nicaragua = 155, - Niger = 156, - Nigeria = 157, - Niue = 158, - NorfolkIsland = 159, - NorthernMarianaIslands = 160, - Norway = 161, - Oman = 162, - Pakistan = 163, - Palau = 164, - PalestinianTerritory = 165, - Panama = 166, - PapuaNewGuinea = 167, - Paraguay = 168, - Peru = 169, - Philippines = 170, - Pitcairn = 171, - Poland = 172, - Portugal = 173, - PuertoRico = 174, - Qatar = 175, - Reunion = 176, - Romania = 177, - RussianFederation = 178, - Rwanda = 179, - SaintKittsAndNevis = 180, - StLucia = 181, - StVincentAndTheGrenadines = 182, - Samoa = 183, - SanMarino = 184, - SaoTomeAndPrincipe = 185, - SaudiArabia = 186, - Senegal = 187, - Seychelles = 188, - SierraLeone = 189, - Singapore = 190, - Slovakia = 191, - Slovenia = 192, - SolomonIslands = 193, - Somalia = 194, - SouthAfrica = 195, - SouthGeorgiaAndTheSouthSandwichIslands = 196, - Spain = 197, - SriLanka = 198, - StHelena = 199, - StPierreAndMiquelon = 200, - Sudan = 201, - Suriname = 202, - SvalbardAndJanMayenIslands = 203, - Swaziland = 204, - Sweden = 205, - Switzerland = 206, - SyrianArabRepublic = 207, - Taiwan = 208, - Tajikistan = 209, - Tanzania = 210, - Thailand = 211, - Togo = 212, - Tokelau = 213, - TongaCountry = 214, - TrinidadAndTobago = 215, - Tunisia = 216, - Turkey = 217, - Turkmenistan = 218, - TurksAndCaicosIslands = 219, - Tuvalu = 220, - Uganda = 221, - Ukraine = 222, - UnitedArabEmirates = 223, - UnitedKingdom = 224, - UnitedStates = 225, - UnitedStatesMinorOutlyingIslands = 226, - Uruguay = 227, - Uzbekistan = 228, - Vanuatu = 229, - VaticanCityState = 230, - Venezuela = 231, - VietNam = 232, - BritishVirginIslands = 233, - USVirginIslands = 234, - WallisAndFutunaIslands = 235, - WesternSahara = 236, - Yemen = 237, - Yugoslavia = 238, - Zambia = 239, - Zimbabwe = 240, - LastCountry = Zimbabwe - }; - - TQLocale(); - TQLocale(const TQString &name); - TQLocale(Language language, Country country = AnyCountry); - TQLocale(const TQLocale &other); - - TQLocale &operator=(const TQLocale &other); - - Language language() const; - Country country() const; - TQString name() const; - - short toShort(const TQString &s, bool *ok = 0) const; - ushort toUShort(const TQString &s, bool *ok = 0) const; - int toInt(const TQString &s, bool *ok = 0) const; - uint toUInt(const TQString &s, bool *ok = 0) const; - TQ_LONG toLong(const TQString &s, bool *ok = 0) const; - TQ_ULONG toULong(const TQString &s, bool *ok = 0) const; - TQ_LLONG toLongLong(const TQString &s, bool *ok = 0) const; - TQ_ULLONG toULongLong(const TQString &s, bool *ok = 0) const; - float toFloat(const TQString &s, bool *ok = 0) const; - double toDouble(const TQString &s, bool *ok = 0) const; - - TQString toString(short i) const - { return toString((TQ_LLONG)i); } - TQString toString(ushort i) const - { return toString((TQ_ULLONG)i); } - TQString toString(int i) const - { return toString((TQ_LLONG)i); } - TQString toString(uint i) const - { return toString((TQ_ULLONG)i); } -#if !defined(Q_OS_WIN64) - TQString toString(TQ_LONG i) const - { return toString((TQ_LLONG)i); } - TQString toString(TQ_ULONG i) const - { return toString((TQ_ULLONG)i); } -#endif - TQString toString(TQ_LLONG i) const; - TQString toString(TQ_ULLONG i) const; - TQString toString(float i, char f = 'g', int prec = 6) const - { return toString((double) i, f, prec); } - TQString toString(double i, char f = 'g', int prec = 6) const; - - static TQString languageToString(Language language); - static TQString countryToString(Country country); - static void setDefault(const TQLocale &locale); - - static TQLocale c() { return TQLocale(C); } - static TQLocale system(); - -private: - const TQLocalePrivate *d; - static const TQLocalePrivate *default_d; -}; - -#endif diff --git a/src/tools/qfeatures.txt b/src/tools/qfeatures.txt index 323f38109..89917cbec 100644 --- a/src/tools/qfeatures.txt +++ b/src/tools/qfeatures.txt @@ -591,7 +591,7 @@ SeeAlso: ??? Feature: LABEL Section: Widgets Requires: FRAME -Name: QLabel +Name: TQLabel SeeAlso: ??? Feature: TOOLBAR diff --git a/src/tools/qglobal.cpp b/src/tools/qglobal.cpp index ff5fd5c74..5e9f38a8a 100644 --- a/src/tools/qglobal.cpp +++ b/src/tools/qglobal.cpp @@ -862,7 +862,7 @@ TQtMsgHandler qInstallMsgHandler( TQtMsgHandler h ) /* Dijkstra's bisection algorithm to find the square root as an integer. Deliberately not exported as part of the TQt API, but used in - qsimplerichtext.cpp + tqsimplerichtext.cpp */ unsigned int qt_int_sqrt( unsigned int n ) { diff --git a/src/tools/qlocale.cpp b/src/tools/qlocale.cpp deleted file mode 100644 index fc02f8ef2..000000000 --- a/src/tools/qlocale.cpp +++ /dev/null @@ -1,6322 +0,0 @@ -/**************************************************************************** -** -** Implementation of the TQLocale class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the tools module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "ntqlocale.h" -#include "qlocale_p.h" -#include "ntqnamespace.h" - -#ifdef QT_QLOCALE_USES_FCVT -# include -# include -#endif - -#if defined (Q_OS_WIN) -# include -# undef NAN // we want to use our fallback on Windows -# undef INFINITY -#endif - -#ifdef Q_OS_LINUX -# include -#endif - -#if defined( Q_OS_MAC ) -# include -#endif - -#if defined (Q_OS_SOLARIS) -# include -#endif - -#if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) -# define INFINITY DBL_INFINITY -# define NAN DBL_QNAN -#endif - -#if (defined(Q_CC_GNU) && defined(Q_OS_WIN)) || __GNUC__ == 4 || defined(QT_QLOCALE_NEEDS_VOLATILE) -# define NEEDS_VOLATILE volatile -#else -# define NEEDS_VOLATILE -#endif - -enum { - LittleEndian, - BigEndian - -#ifdef TQ_BYTE_ORDER -# if TQ_BYTE_ORDER == TQ_BIG_ENDIAN - , ByteOrder = BigEndian -# elif TQ_BYTE_ORDER == TQ_LITTLE_ENDIAN - , ByteOrder = LittleEndian -# else -# error "undefined byte order" -# endif -}; -#else -}; -static const unsigned int one = 1; -static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); -#endif - -#if !defined(INFINITY) -static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; -static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; -static inline double inf() -{ - return (ByteOrder == BigEndian ? - *((const double *) be_inf_bytes) : - *((const double *) le_inf_bytes)); -} -# define INFINITY (::inf()) -#endif - -#if !defined(NAN) -static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; -static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; -static inline double nan() -{ - return (ByteOrder == BigEndian ? - *((const double *) be_nan_bytes) : - *((const double *) le_nan_bytes)); -} -# define NAN (::nan()) -#endif - -// We can't rely on -NAN, since all operations on a NAN should return a NAN. -static double be_neg_nan; -static double le_neg_nan; -static const unsigned char be_neg_nan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 }; -static const unsigned char le_neg_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff }; -static bool neg_nan_init = false; - -static inline double negNan() -{ - if (!neg_nan_init) - { - memcpy(&be_neg_nan,be_neg_nan_bytes,sizeof(be_neg_nan_bytes)); - memcpy(&le_neg_nan,le_neg_nan_bytes,sizeof(le_neg_nan_bytes)); - neg_nan_init = true; - } - return (ByteOrder == BigEndian ? - be_neg_nan : - le_neg_nan); - -} - -// Sizes as defined by the ISO C99 standard - fallback -#ifndef LLONG_MAX -# define LLONG_MAX TQ_INT64_C(9223372036854775807) -#endif -#ifndef LLONG_MIN -# define LLONG_MIN (-LLONG_MAX - TQ_INT64_C(1)) -#endif -#ifndef ULLONG_MAX -# define ULLONG_MAX TQ_UINT64_C(0xffffffffffffffff) -#endif - -#ifndef QT_QLOCALE_USES_FCVT -static char *qdtoa(double d, int mode, int ndigits, int *decpt, - int *sign, char **rve, char **digits_str); -static char *_qdtoa(double d, int mode, int ndigits, int *decpt, - int *sign, char **rve, char **digits_str); -static double qstrtod(const char *s00, char const **se, bool *ok); -#endif -static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok); -static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok); - -static inline bool compareBits(double d1, double d2) -{ - return memcmp((const char*)&d1, (const char*)&d2, sizeof(double)) == 0; -} - -static inline bool qIsInf(double d) -{ - return compareBits(d, INFINITY) || compareBits(d, -INFINITY); -} - -static inline bool qIsNan(double d) -{ - return compareBits(d, NAN) || compareBits(d, negNan()); -} - -static const uint locale_index[] = { - 0, // unused - 0, // C - 0, // Abkhazian - 0, // Afan - 0, // Afar - 1, // Afrikaans - 2, // Albanian - 0, // Amharic - 3, // Arabic - 19, // Armenian - 0, // Assamese - 0, // Aymara - 20, // Azerbaijani - 0, // Bashkir - 21, // Basque - 22, // Bengali - 0, // Bhutani - 0, // Bihari - 0, // Bislama - 0, // Breton - 23, // Bulgarian - 0, // Burmese - 24, // Byelorussian - 0, // Cambodian - 25, // Catalan - 26, // Chinese - 0, // Corsican - 31, // Croatian - 32, // Czech - 33, // Danish - 34, // Dutch - 36, // English - 0, // Esperanto - 48, // Estonian - 49, // Faroese - 0, // Fiji - 50, // Finnish - 51, // French - 0, // Frisian - 0, // Gaelic - 57, // Galician - 58, // Georgian - 59, // German - 64, // Greek - 0, // Greenlandic - 0, // Guarani - 65, // Gujarati - 0, // Hausa - 66, // Hebrew - 67, // Hindi - 68, // Hungarian - 69, // Icelandic - 70, // Indonesian - 0, // Interlingua - 0, // Interlingue - 0, // Inuktitut - 0, // Inupiak - 0, // Irish - 71, // Italian - 73, // Japanese - 0, // Javanese - 74, // Kannada - 0, // Kashmiri - 75, // Kazakh - 0, // Kinyarwanda - 76, // Kirghiz - 77, // Korean - 0, // Kurdish - 0, // Kurundi - 0, // Laothian - 0, // Latin - 78, // Latvian - 0, // Lingala - 79, // Lithuanian - 80, // Macedonian - 0, // Malagasy - 81, // Malay - 0, // Malayalam - 0, // Maltese - 0, // Maori - 83, // Marathi - 0, // Moldavian - 84, // Mongolian - 0, // Nauru - 0, // Nepali - 85, // Norwegian - 0, // Occitan - 0, // Oriya - 0, // Pashto - 86, // Persian - 87, // Polish - 88, // Portuguese - 90, // Punjabi - 0, // Quechua - 0, // RhaetoRomance - 91, // Romanian - 92, // Russian - 0, // Samoan - 0, // Sangho - 93, // Sanskrit - 0, // Serbian - 0, // SerboCroatian - 0, // Sesotho - 0, // Setswana - 0, // Shona - 0, // Sindhi - 0, // Singhalese - 0, // Siswati - 94, // Slovak - 95, // Slovenian - 0, // Somali - 96, // Spanish - 0, // Sundanese - 115, // Swahili - 116, // Swedish - 0, // Tagalog - 0, // Tajik - 118, // Tamil - 0, // Tatar - 119, // Telugu - 120, // Thai - 0, // Tibetan - 0, // Tigrinya - 0, // Tonga - 0, // Tsonga - 121, // Turkish - 0, // Turkmen - 0, // Twi - 0, // Uigur - 122, // Ukrainian - 123, // Urdu - 124, // Uzbek - 125, // Vietnamese - 0, // Volapuk - 0, // Welsh - 0, // Wolof - 0, // Xhosa - 0, // Yiddish - 0, // Yoruba - 0, // Zhuang - 0, // Zulu - 0 // trailing 0 -}; - -static const TQLocalePrivate locale_data[] = { -// lang terr dec group list prcnt zero minus exp - { 1, 0, 46, 44, 59, 37, 48, 45, 101 }, // C/AnyCountry - { 5, 195, 46, 44, 44, 37, 48, 45, 101 }, // Afrikaans/SouthAfrica - { 6, 2, 44, 46, 59, 37, 48, 45, 101 }, // Albanian/Albania - { 8, 186, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SaudiArabia - { 8, 3, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Algeria - { 8, 17, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Bahrain - { 8, 64, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Egypt - { 8, 103, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Iraq - { 8, 109, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Jordan - { 8, 115, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Kuwait - { 8, 119, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Lebanon - { 8, 122, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/LibyanArabJamahiriya - { 8, 145, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Morocco - { 8, 162, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Oman - { 8, 175, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Qatar - { 8, 207, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SyrianArabRepublic - { 8, 216, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Tunisia - { 8, 223, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/UnitedArabEmirates - { 8, 237, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Yemen - { 9, 11, 46, 44, 44, 37, 48, 45, 101 }, // Armenian/Armenia - { 12, 15, 44, 160, 59, 37, 48, 45, 101 }, // Azerbaijani/Azerbaijan - { 14, 197, 44, 46, 59, 37, 48, 45, 101 }, // Basque/Spain - { 15, 100, 46, 44, 59, 37, 48, 45, 101 }, // Bengali/India - { 20, 33, 44, 160, 59, 37, 48, 45, 101 }, // Bulgarian/Bulgaria - { 22, 20, 44, 160, 59, 37, 48, 45, 101 }, // Byelorussian/Belarus - { 24, 197, 44, 46, 59, 37, 48, 45, 101 }, // Catalan/Spain - { 25, 44, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/China - { 25, 97, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/HongKong - { 25, 126, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Macau - { 25, 190, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Singapore - { 25, 208, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Taiwan - { 27, 54, 44, 46, 59, 37, 48, 45, 101 }, // Croatian/Croatia - { 28, 57, 44, 160, 59, 37, 48, 45, 101 }, // Czech/CzechRepublic - { 29, 58, 44, 46, 59, 37, 48, 45, 101 }, // Danish/Denmark - { 30, 151, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Netherlands - { 30, 21, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Belgium - { 31, 225, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedStates - { 31, 13, 46, 44, 44, 37, 48, 45, 101 }, // English/Australia - { 31, 22, 46, 44, 59, 37, 48, 45, 101 }, // English/Belize - { 31, 38, 46, 44, 44, 37, 48, 45, 101 }, // English/Canada - { 31, 104, 46, 44, 44, 37, 48, 45, 101 }, // English/Ireland - { 31, 107, 46, 44, 44, 37, 48, 45, 101 }, // English/Jamaica - { 31, 154, 46, 44, 44, 37, 48, 45, 101 }, // English/NewZealand - { 31, 170, 46, 44, 44, 37, 48, 45, 101 }, // English/Philippines - { 31, 195, 46, 44, 44, 37, 48, 45, 101 }, // English/SouthAfrica - { 31, 215, 46, 44, 59, 37, 48, 45, 101 }, // English/TrinidadAndTobago - { 31, 224, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedKingdom - { 31, 240, 46, 44, 44, 37, 48, 45, 101 }, // English/Zimbabwe - { 33, 68, 44, 160, 59, 37, 48, 45, 101 }, // Estonian/Estonia - { 34, 71, 44, 46, 59, 37, 48, 45, 101 }, // Faroese/FaroeIslands - { 36, 73, 44, 160, 59, 37, 48, 45, 101 }, // Finnish/Finland - { 37, 74, 44, 160, 59, 37, 48, 45, 101 }, // French/France - { 37, 21, 44, 46, 59, 37, 48, 45, 101 }, // French/Belgium - { 37, 38, 44, 160, 59, 37, 48, 45, 101 }, // French/Canada - { 37, 125, 44, 160, 59, 37, 48, 45, 101 }, // French/Luxembourg - { 37, 142, 44, 160, 59, 37, 48, 45, 101 }, // French/Monaco - { 37, 206, 46, 39, 59, 37, 48, 45, 101 }, // French/Switzerland - { 40, 197, 44, 46, 44, 37, 48, 45, 101 }, // Galician/Spain - { 41, 81, 44, 160, 59, 37, 48, 45, 101 }, // Georgian/Georgia - { 42, 82, 44, 46, 59, 37, 48, 45, 101 }, // German/Germany - { 42, 14, 44, 46, 59, 37, 48, 45, 101 }, // German/Austria - { 42, 123, 46, 39, 59, 37, 48, 45, 101 }, // German/Liechtenstein - { 42, 125, 44, 46, 59, 37, 48, 45, 101 }, // German/Luxembourg - { 42, 206, 46, 39, 59, 37, 48, 45, 101 }, // German/Switzerland - { 43, 85, 44, 46, 59, 37, 48, 45, 101 }, // Greek/Greece - { 46, 100, 46, 44, 44, 37, 2790, 45, 101 }, // Gujarati/India - { 48, 105, 46, 44, 44, 37, 48, 45, 101 }, // Hebrew/Israel - { 49, 100, 46, 44, 44, 37, 48, 45, 101 }, // Hindi/India - { 50, 98, 44, 160, 59, 37, 48, 45, 101 }, // Hungarian/Hungary - { 51, 99, 44, 46, 59, 37, 48, 45, 101 }, // Icelandic/Iceland - { 52, 101, 44, 46, 59, 37, 48, 45, 101 }, // Indonesian/Indonesia - { 58, 106, 44, 46, 59, 37, 48, 45, 101 }, // Italian/Italy - { 58, 206, 46, 39, 59, 37, 48, 45, 101 }, // Italian/Switzerland - { 59, 108, 46, 44, 44, 37, 48, 45, 101 }, // Japanese/Japan - { 61, 100, 46, 44, 44, 37, 3302, 45, 101 }, // Kannada/India - { 63, 110, 44, 160, 59, 37, 48, 45, 101 }, // Kazakh/Kazakhstan - { 65, 116, 44, 160, 59, 37, 48, 45, 101 }, // Kirghiz/Kyrgyzstan - { 66, 114, 46, 44, 44, 37, 48, 45, 101 }, // Korean/RepublicOfKorea - { 71, 118, 44, 160, 59, 37, 48, 45, 101 }, // Latvian/Latvia - { 73, 124, 44, 46, 59, 37, 48, 45, 101 }, // Lithuanian/Lithuania - { 74, 127, 44, 46, 59, 37, 48, 45, 101 }, // Macedonian/Macedonia - { 76, 130, 44, 46, 59, 37, 48, 45, 101 }, // Malay/Malaysia - { 76, 32, 44, 46, 59, 37, 48, 45, 101 }, // Malay/BruneiDarussalam - { 80, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Marathi/India - { 82, 143, 44, 160, 59, 37, 48, 45, 101 }, // Mongolian/Mongolia - { 85, 161, 44, 160, 59, 37, 48, 45, 101 }, // Norwegian/Norway - { 89, 102, 46, 44, 59, 37, 1776, 45, 101 }, // Persian/Iran - { 90, 172, 44, 160, 59, 37, 48, 45, 101 }, // Polish/Poland - { 91, 173, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Portugal - { 91, 30, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Brazil - { 92, 100, 46, 44, 44, 37, 2662, 45, 101 }, // Punjabi/India - { 95, 177, 44, 46, 59, 37, 48, 45, 101 }, // Romanian/Romania - { 96, 178, 44, 160, 59, 37, 48, 45, 101 }, // Russian/RussianFederation - { 99, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Sanskrit/India - { 108, 191, 44, 160, 59, 37, 48, 45, 101 }, // Slovak/Slovakia - { 109, 192, 44, 46, 59, 37, 48, 45, 101 }, // Slovenian/Slovenia - { 111, 197, 44, 46, 59, 37, 48, 45, 101 }, // Spanish/Spain - { 111, 10, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Argentina - { 111, 26, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Bolivia - { 111, 43, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Chile - { 111, 47, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Colombia - { 111, 52, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/CostaRica - { 111, 61, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/DominicanRepublic - { 111, 63, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Ecuador - { 111, 65, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/ElSalvador - { 111, 90, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Guatemala - { 111, 96, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Honduras - { 111, 139, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Mexico - { 111, 155, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Nicaragua - { 111, 166, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Panama - { 111, 168, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Paraguay - { 111, 169, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Peru - { 111, 174, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/PuertoRico - { 111, 227, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Uruguay - { 111, 231, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Venezuela - { 113, 111, 46, 44, 44, 37, 48, 45, 101 }, // Swahili/Kenya - { 114, 205, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Sweden - { 114, 73, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Finland - { 117, 100, 46, 44, 44, 37, 48, 45, 101 }, // Tamil/India - { 119, 100, 46, 44, 44, 37, 3174, 45, 101 }, // Telugu/India - { 120, 211, 46, 44, 44, 37, 3664, 45, 101 }, // Thai/Thailand - { 125, 217, 44, 46, 59, 37, 48, 45, 101 }, // Turkish/Turkey - { 129, 222, 44, 160, 59, 37, 48, 45, 101 }, // Ukrainian/Ukraine - { 130, 163, 46, 44, 59, 37, 1776, 45, 101 }, // Urdu/Pakistan - { 131, 228, 44, 160, 59, 37, 48, 45, 101 }, // Uzbek/Uzbekistan - { 132, 232, 44, 46, 44, 37, 48, 45, 101 }, // Vietnamese/VietNam - { 0, 0, 0, 0, 0, 0, 0, 0, 0 } // trailing 0s -}; - -static const char language_name_list[] = -"Default\0" -"C\0" -"Abkhazian\0" -"Afan\0" -"Afar\0" -"Afrikaans\0" -"Albanian\0" -"Amharic\0" -"Arabic\0" -"Armenian\0" -"Assamese\0" -"Aymara\0" -"Azerbaijani\0" -"Bashkir\0" -"Basque\0" -"Bengali\0" -"Bhutani\0" -"Bihari\0" -"Bislama\0" -"Breton\0" -"Bulgarian\0" -"Burmese\0" -"Byelorussian\0" -"Cambodian\0" -"Catalan\0" -"Chinese\0" -"Corsican\0" -"Croatian\0" -"Czech\0" -"Danish\0" -"Dutch\0" -"English\0" -"Esperanto\0" -"Estonian\0" -"Faroese\0" -"Fiji\0" -"Finnish\0" -"French\0" -"Frisian\0" -"Gaelic\0" -"Galician\0" -"Georgian\0" -"German\0" -"Greek\0" -"Greenlandic\0" -"Guarani\0" -"Gujarati\0" -"Hausa\0" -"Hebrew\0" -"Hindi\0" -"Hungarian\0" -"Icelandic\0" -"Indonesian\0" -"Interlingua\0" -"Interlingue\0" -"Inuktitut\0" -"Inupiak\0" -"Irish\0" -"Italian\0" -"Japanese\0" -"Javanese\0" -"Kannada\0" -"Kashmiri\0" -"Kazakh\0" -"Kinyarwanda\0" -"Kirghiz\0" -"Korean\0" -"Kurdish\0" -"Kurundi\0" -"Laothian\0" -"Latin\0" -"Latvian\0" -"Lingala\0" -"Lithuanian\0" -"Macedonian\0" -"Malagasy\0" -"Malay\0" -"Malayalam\0" -"Maltese\0" -"Maori\0" -"Marathi\0" -"Moldavian\0" -"Mongolian\0" -"Nauru\0" -"Nepali\0" -"Norwegian\0" -"Occitan\0" -"Oriya\0" -"Pashto\0" -"Persian\0" -"Polish\0" -"Portuguese\0" -"Punjabi\0" -"Quechua\0" -"RhaetoRomance\0" -"Romanian\0" -"Russian\0" -"Samoan\0" -"Sangho\0" -"Sanskrit\0" -"Serbian\0" -"SerboCroatian\0" -"Sesotho\0" -"Setswana\0" -"Shona\0" -"Sindhi\0" -"Singhalese\0" -"Siswati\0" -"Slovak\0" -"Slovenian\0" -"Somali\0" -"Spanish\0" -"Sundanese\0" -"Swahili\0" -"Swedish\0" -"Tagalog\0" -"Tajik\0" -"Tamil\0" -"Tatar\0" -"Telugu\0" -"Thai\0" -"Tibetan\0" -"Tigrinya\0" -"Tonga\0" -"Tsonga\0" -"Turkish\0" -"Turkmen\0" -"Twi\0" -"Uigur\0" -"Ukrainian\0" -"Urdu\0" -"Uzbek\0" -"Vietnamese\0" -"Volapuk\0" -"Welsh\0" -"Wolof\0" -"Xhosa\0" -"Yiddish\0" -"Yoruba\0" -"Zhuang\0" -"Zulu\0"; - -static const uint language_name_index[] = { - 0,// Unused - 8,// C - 10,// Abkhazian - 20,// Afan - 25,// Afar - 30,// Afrikaans - 40,// Albanian - 49,// Amharic - 57,// Arabic - 64,// Armenian - 73,// Assamese - 82,// Aymara - 89,// Azerbaijani - 101,// Bashkir - 109,// Basque - 116,// Bengali - 124,// Bhutani - 132,// Bihari - 139,// Bislama - 147,// Breton - 154,// Bulgarian - 164,// Burmese - 172,// Byelorussian - 185,// Cambodian - 195,// Catalan - 203,// Chinese - 211,// Corsican - 220,// Croatian - 229,// Czech - 235,// Danish - 242,// Dutch - 248,// English - 256,// Esperanto - 266,// Estonian - 275,// Faroese - 283,// Fiji - 288,// Finnish - 296,// French - 303,// Frisian - 311,// Gaelic - 318,// Galician - 327,// Georgian - 336,// German - 343,// Greek - 349,// Greenlandic - 361,// Guarani - 369,// Gujarati - 378,// Hausa - 384,// Hebrew - 391,// Hindi - 397,// Hungarian - 407,// Icelandic - 417,// Indonesian - 428,// Interlingua - 440,// Interlingue - 452,// Inuktitut - 462,// Inupiak - 470,// Irish - 476,// Italian - 484,// Japanese - 493,// Javanese - 502,// Kannada - 510,// Kashmiri - 519,// Kazakh - 526,// Kinyarwanda - 538,// Kirghiz - 546,// Korean - 553,// Kurdish - 561,// Kurundi - 569,// Laothian - 578,// Latin - 584,// Latvian - 592,// Lingala - 600,// Lithuanian - 611,// Macedonian - 622,// Malagasy - 631,// Malay - 637,// Malayalam - 647,// Maltese - 655,// Maori - 661,// Marathi - 669,// Moldavian - 679,// Mongolian - 689,// Nauru - 695,// Nepali - 702,// Norwegian - 712,// Occitan - 720,// Oriya - 726,// Pashto - 733,// Persian - 741,// Polish - 748,// Portuguese - 759,// Punjabi - 767,// Quechua - 775,// RhaetoRomance - 789,// Romanian - 798,// Russian - 806,// Samoan - 813,// Sangho - 820,// Sanskrit - 829,// Serbian - 837,// SerboCroatian - 851,// Sesotho - 859,// Setswana - 868,// Shona - 874,// Sindhi - 881,// Singhalese - 892,// Siswati - 900,// Slovak - 907,// Slovenian - 917,// Somali - 924,// Spanish - 932,// Sundanese - 942,// Swahili - 950,// Swedish - 958,// Tagalog - 966,// Tajik - 972,// Tamil - 978,// Tatar - 984,// Telugu - 991,// Thai - 996,// Tibetan - 1004,// Tigrinya - 1013,// Tonga - 1019,// Tsonga - 1026,// Turkish - 1034,// Turkmen - 1042,// Twi - 1046,// Uigur - 1052,// Ukrainian - 1062,// Urdu - 1067,// Uzbek - 1073,// Vietnamese - 1084,// Volapuk - 1092,// Welsh - 1098,// Wolof - 1104,// Xhosa - 1110,// Yiddish - 1118,// Yoruba - 1125,// Zhuang - 1132// Zulu -}; - -static const char country_name_list[] = -"Default\0" -"Afghanistan\0" -"Albania\0" -"Algeria\0" -"AmericanSamoa\0" -"Andorra\0" -"Angola\0" -"Anguilla\0" -"Antarctica\0" -"AntiguaAndBarbuda\0" -"Argentina\0" -"Armenia\0" -"Aruba\0" -"Australia\0" -"Austria\0" -"Azerbaijan\0" -"Bahamas\0" -"Bahrain\0" -"Bangladesh\0" -"Barbados\0" -"Belarus\0" -"Belgium\0" -"Belize\0" -"Benin\0" -"Bermuda\0" -"Bhutan\0" -"Bolivia\0" -"BosniaAndHerzegowina\0" -"Botswana\0" -"BouvetIsland\0" -"Brazil\0" -"BritishIndianOceanTerritory\0" -"BruneiDarussalam\0" -"Bulgaria\0" -"BurkinaFaso\0" -"Burundi\0" -"Cambodia\0" -"Cameroon\0" -"Canada\0" -"CapeVerde\0" -"CaymanIslands\0" -"CentralAfricanRepublic\0" -"Chad\0" -"Chile\0" -"China\0" -"ChristmasIsland\0" -"CocosIslands\0" -"Colombia\0" -"Comoros\0" -"DemocraticRepublicOfCongo\0" -"PeoplesRepublicOfCongo\0" -"CookIslands\0" -"CostaRica\0" -"IvoryCoast\0" -"Croatia\0" -"Cuba\0" -"Cyprus\0" -"CzechRepublic\0" -"Denmark\0" -"Djibouti\0" -"Dominica\0" -"DominicanRepublic\0" -"EastTimor\0" -"Ecuador\0" -"Egypt\0" -"ElSalvador\0" -"EquatorialGuinea\0" -"Eritrea\0" -"Estonia\0" -"Ethiopia\0" -"FalklandIslands\0" -"FaroeIslands\0" -"Fiji\0" -"Finland\0" -"France\0" -"MetropolitanFrance\0" -"FrenchGuiana\0" -"FrenchPolynesia\0" -"FrenchSouthernTerritories\0" -"Gabon\0" -"Gambia\0" -"Georgia\0" -"Germany\0" -"Ghana\0" -"Gibraltar\0" -"Greece\0" -"Greenland\0" -"Grenada\0" -"Guadeloupe\0" -"Guam\0" -"Guatemala\0" -"Guinea\0" -"GuineaBissau\0" -"Guyana\0" -"Haiti\0" -"HeardAndMcDonaldIslands\0" -"Honduras\0" -"HongKong\0" -"Hungary\0" -"Iceland\0" -"India\0" -"Indonesia\0" -"Iran\0" -"Iraq\0" -"Ireland\0" -"Israel\0" -"Italy\0" -"Jamaica\0" -"Japan\0" -"Jordan\0" -"Kazakhstan\0" -"Kenya\0" -"Kiribati\0" -"DemocraticRepublicOfKorea\0" -"RepublicOfKorea\0" -"Kuwait\0" -"Kyrgyzstan\0" -"Lao\0" -"Latvia\0" -"Lebanon\0" -"Lesotho\0" -"Liberia\0" -"LibyanArabJamahiriya\0" -"Liechtenstein\0" -"Lithuania\0" -"Luxembourg\0" -"Macau\0" -"Macedonia\0" -"Madagascar\0" -"Malawi\0" -"Malaysia\0" -"Maldives\0" -"Mali\0" -"Malta\0" -"MarshallIslands\0" -"Martinique\0" -"Mauritania\0" -"Mauritius\0" -"Mayotte\0" -"Mexico\0" -"Micronesia\0" -"Moldova\0" -"Monaco\0" -"Mongolia\0" -"Montserrat\0" -"Morocco\0" -"Mozambique\0" -"Myanmar\0" -"Namibia\0" -"Nauru\0" -"Nepal\0" -"Netherlands\0" -"NetherlandsAntilles\0" -"NewCaledonia\0" -"NewZealand\0" -"Nicaragua\0" -"Niger\0" -"Nigeria\0" -"Niue\0" -"NorfolkIsland\0" -"NorthernMarianaIslands\0" -"Norway\0" -"Oman\0" -"Pakistan\0" -"Palau\0" -"PalestinianTerritory\0" -"Panama\0" -"PapuaNewGuinea\0" -"Paraguay\0" -"Peru\0" -"Philippines\0" -"Pitcairn\0" -"Poland\0" -"Portugal\0" -"PuertoRico\0" -"Qatar\0" -"Reunion\0" -"Romania\0" -"RussianFederation\0" -"Rwanda\0" -"SaintKittsAndNevis\0" -"StLucia\0" -"StVincentAndTheGrenadines\0" -"Samoa\0" -"SanMarino\0" -"SaoTomeAndPrincipe\0" -"SaudiArabia\0" -"Senegal\0" -"Seychelles\0" -"SierraLeone\0" -"Singapore\0" -"Slovakia\0" -"Slovenia\0" -"SolomonIslands\0" -"Somalia\0" -"SouthAfrica\0" -"SouthGeorgiaAndTheSouthSandwichIslands\0" -"Spain\0" -"SriLanka\0" -"StHelena\0" -"StPierreAndMiquelon\0" -"Sudan\0" -"Suriname\0" -"SvalbardAndJanMayenIslands\0" -"Swaziland\0" -"Sweden\0" -"Switzerland\0" -"SyrianArabRepublic\0" -"Taiwan\0" -"Tajikistan\0" -"Tanzania\0" -"Thailand\0" -"Togo\0" -"Tokelau\0" -"Tonga\0" -"TrinidadAndTobago\0" -"Tunisia\0" -"Turkey\0" -"Turkmenistan\0" -"TurksAndCaicosIslands\0" -"Tuvalu\0" -"Uganda\0" -"Ukraine\0" -"UnitedArabEmirates\0" -"UnitedKingdom\0" -"UnitedStates\0" -"UnitedStatesMinorOutlyingIslands\0" -"Uruguay\0" -"Uzbekistan\0" -"Vanuatu\0" -"VaticanCityState\0" -"Venezuela\0" -"VietNam\0" -"BritishVirginIslands\0" -"USVirginIslands\0" -"WallisAndFutunaIslands\0" -"WesternSahara\0" -"Yemen\0" -"Yugoslavia\0" -"Zambia\0" -"Zimbabwe\0"; - -static const uint country_name_index[] = { - 0,// AnyCountry - 8,// Afghanistan - 20,// Albania - 28,// Algeria - 36,// AmericanSamoa - 50,// Andorra - 58,// Angola - 65,// Anguilla - 74,// Antarctica - 85,// AntiguaAndBarbuda - 103,// Argentina - 113,// Armenia - 121,// Aruba - 127,// Australia - 137,// Austria - 145,// Azerbaijan - 156,// Bahamas - 164,// Bahrain - 172,// Bangladesh - 183,// Barbados - 192,// Belarus - 200,// Belgium - 208,// Belize - 215,// Benin - 221,// Bermuda - 229,// Bhutan - 236,// Bolivia - 244,// BosniaAndHerzegowina - 265,// Botswana - 274,// BouvetIsland - 287,// Brazil - 294,// BritishIndianOceanTerritory - 322,// BruneiDarussalam - 339,// Bulgaria - 348,// BurkinaFaso - 360,// Burundi - 368,// Cambodia - 377,// Cameroon - 386,// Canada - 393,// CapeVerde - 403,// CaymanIslands - 417,// CentralAfricanRepublic - 440,// Chad - 445,// Chile - 451,// China - 457,// ChristmasIsland - 473,// CocosIslands - 486,// Colombia - 495,// Comoros - 503,// DemocraticRepublicOfCongo - 529,// PeoplesRepublicOfCongo - 552,// CookIslands - 564,// CostaRica - 574,// IvoryCoast - 585,// Croatia - 593,// Cuba - 598,// Cyprus - 605,// CzechRepublic - 619,// Denmark - 627,// Djibouti - 636,// Dominica - 645,// DominicanRepublic - 663,// EastTimor - 673,// Ecuador - 681,// Egypt - 687,// ElSalvador - 698,// EquatorialGuinea - 715,// Eritrea - 723,// Estonia - 731,// Ethiopia - 740,// FalklandIslands - 756,// FaroeIslands - 769,// Fiji - 774,// Finland - 782,// France - 789,// MetropolitanFrance - 808,// FrenchGuiana - 821,// FrenchPolynesia - 837,// FrenchSouthernTerritories - 863,// Gabon - 869,// Gambia - 876,// Georgia - 884,// Germany - 892,// Ghana - 898,// Gibraltar - 908,// Greece - 915,// Greenland - 925,// Grenada - 933,// Guadeloupe - 944,// Guam - 949,// Guatemala - 959,// Guinea - 966,// GuineaBissau - 979,// Guyana - 986,// Haiti - 992,// HeardAndMcDonaldIslands - 1016,// Honduras - 1025,// HongKong - 1034,// Hungary - 1042,// Iceland - 1050,// India - 1056,// Indonesia - 1066,// Iran - 1071,// Iraq - 1076,// Ireland - 1084,// Israel - 1091,// Italy - 1097,// Jamaica - 1105,// Japan - 1111,// Jordan - 1118,// Kazakhstan - 1129,// Kenya - 1135,// Kiribati - 1144,// DemocraticRepublicOfKorea - 1170,// RepublicOfKorea - 1186,// Kuwait - 1193,// Kyrgyzstan - 1204,// Lao - 1208,// Latvia - 1215,// Lebanon - 1223,// Lesotho - 1231,// Liberia - 1239,// LibyanArabJamahiriya - 1260,// Liechtenstein - 1274,// Lithuania - 1284,// Luxembourg - 1295,// Macau - 1301,// Macedonia - 1311,// Madagascar - 1322,// Malawi - 1329,// Malaysia - 1338,// Maldives - 1347,// Mali - 1352,// Malta - 1358,// MarshallIslands - 1374,// Martinique - 1385,// Mauritania - 1396,// Mauritius - 1406,// Mayotte - 1414,// Mexico - 1421,// Micronesia - 1432,// Moldova - 1440,// Monaco - 1447,// Mongolia - 1456,// Montserrat - 1467,// Morocco - 1475,// Mozambique - 1486,// Myanmar - 1494,// Namibia - 1502,// Nauru - 1508,// Nepal - 1514,// Netherlands - 1526,// NetherlandsAntilles - 1546,// NewCaledonia - 1559,// NewZealand - 1570,// Nicaragua - 1580,// Niger - 1586,// Nigeria - 1594,// Niue - 1599,// NorfolkIsland - 1613,// NorthernMarianaIslands - 1636,// Norway - 1643,// Oman - 1648,// Pakistan - 1657,// Palau - 1663,// PalestinianTerritory - 1684,// Panama - 1691,// PapuaNewGuinea - 1706,// Paraguay - 1715,// Peru - 1720,// Philippines - 1732,// Pitcairn - 1741,// Poland - 1748,// Portugal - 1757,// PuertoRico - 1768,// Qatar - 1774,// Reunion - 1782,// Romania - 1790,// RussianFederation - 1808,// Rwanda - 1815,// SaintKittsAndNevis - 1834,// StLucia - 1842,// StVincentAndTheGrenadines - 1868,// Samoa - 1874,// SanMarino - 1884,// SaoTomeAndPrincipe - 1903,// SaudiArabia - 1915,// Senegal - 1923,// Seychelles - 1934,// SierraLeone - 1946,// Singapore - 1956,// Slovakia - 1965,// Slovenia - 1974,// SolomonIslands - 1989,// Somalia - 1997,// SouthAfrica - 2009,// SouthGeorgiaAndTheSouthSandwichIslands - 2048,// Spain - 2054,// SriLanka - 2063,// StHelena - 2072,// StPierreAndMiquelon - 2092,// Sudan - 2098,// Suriname - 2107,// SvalbardAndJanMayenIslands - 2134,// Swaziland - 2144,// Sweden - 2151,// Switzerland - 2163,// SyrianArabRepublic - 2182,// Taiwan - 2189,// Tajikistan - 2200,// Tanzania - 2209,// Thailand - 2218,// Togo - 2223,// Tokelau - 2231,// Tonga - 2237,// TrinidadAndTobago - 2255,// Tunisia - 2263,// Turkey - 2270,// Turkmenistan - 2283,// TurksAndCaicosIslands - 2305,// Tuvalu - 2312,// Uganda - 2319,// Ukraine - 2327,// UnitedArabEmirates - 2346,// UnitedKingdom - 2360,// UnitedStates - 2373,// UnitedStatesMinorOutlyingIslands - 2406,// Uruguay - 2414,// Uzbekistan - 2425,// Vanuatu - 2433,// VaticanCityState - 2450,// Venezuela - 2460,// VietNam - 2468,// BritishVirginIslands - 2489,// USVirginIslands - 2505,// WallisAndFutunaIslands - 2528,// WesternSahara - 2542,// Yemen - 2548,// Yugoslavia - 2559,// Zambia - 2566// Zimbabwe -}; - -static const char language_code_list[] = -" " // Unused -" " // C -"ab" // Abkhazian -"om" // Afan -"aa" // Afar -"af" // Afrikaans -"sq" // Albanian -"am" // Amharic -"ar" // Arabic -"hy" // Armenian -"as" // Assamese -"ay" // Aymara -"az" // Azerbaijani -"ba" // Bashkir -"eu" // Basque -"bn" // Bengali -"dz" // Bhutani -"bh" // Bihari -"bi" // Bislama -"br" // Breton -"bg" // Bulgarian -"my" // Burmese -"be" // Byelorussian -"km" // Cambodian -"ca" // Catalan -"zh" // Chinese -"co" // Corsican -"hr" // Croatian -"cs" // Czech -"da" // Danish -"nl" // Dutch -"en" // English -"eo" // Esperanto -"et" // Estonian -"fo" // Faroese -"fj" // Fiji -"fi" // Finnish -"fr" // French -"fy" // Frisian -"gd" // Gaelic -"gl" // Galician -"ka" // Georgian -"de" // German -"el" // Greek -"kl" // Greenlandic -"gn" // Guarani -"gu" // Gujarati -"ha" // Hausa -"he" // Hebrew -"hi" // Hindi -"hu" // Hungarian -"is" // Icelandic -"id" // Indonesian -"ia" // Interlingua -"ie" // Interlingue -"iu" // Inuktitut -"ik" // Inupiak -"ga" // Irish -"it" // Italian -"ja" // Japanese -"jv" // Javanese -"kn" // Kannada -"ks" // Kashmiri -"kk" // Kazakh -"rw" // Kinyarwanda -"ky" // Kirghiz -"ko" // Korean -"ku" // Kurdish -"rn" // Kurundi -"lo" // Laothian -"la" // Latin -"lv" // Latvian -"ln" // Lingala -"lt" // Lithuanian -"mk" // Macedonian -"mg" // Malagasy -"ms" // Malay -"ml" // Malayalam -"mt" // Maltese -"mi" // Maori -"mr" // Marathi -"mo" // Moldavian -"mn" // Mongolian -"na" // Nauru -"ne" // Nepali -"no" // Norwegian -"oc" // Occitan -"or" // Oriya -"ps" // Pashto -"fa" // Persian -"pl" // Polish -"pt" // Portuguese -"pa" // Punjabi -"qu" // Quechua -"rm" // RhaetoRomance -"ro" // Romanian -"ru" // Russian -"sm" // Samoan -"sg" // Sangho -"sa" // Sanskrit -"sr" // Serbian -"sh" // SerboCroatian -"st" // Sesotho -"tn" // Setswana -"sn" // Shona -"sd" // Sindhi -"si" // Singhalese -"ss" // Siswati -"sk" // Slovak -"sl" // Slovenian -"so" // Somali -"es" // Spanish -"su" // Sundanese -"sw" // Swahili -"sv" // Swedish -"tl" // Tagalog -"tg" // Tajik -"ta" // Tamil -"tt" // Tatar -"te" // Telugu -"th" // Thai -"bo" // Tibetan -"ti" // Tigrinya -"to" // Tonga -"ts" // Tsonga -"tr" // Turkish -"tk" // Turkmen -"tw" // Twi -"ug" // Uigur -"uk" // Ukrainian -"ur" // Urdu -"uz" // Uzbek -"vi" // Vietnamese -"vo" // Volapuk -"cy" // Welsh -"wo" // Wolof -"xh" // Xhosa -"yi" // Yiddish -"yo" // Yoruba -"za" // Zhuang -"zu" // Zulu -; - -static const char country_code_list[] = -" " // AnyLanguage -"AF" // Afghanistan -"AL" // Albania -"DZ" // Algeria -"AS" // AmericanSamoa -"AD" // Andorra -"AO" // Angola -"AI" // Anguilla -"AQ" // Antarctica -"AG" // AntiguaAndBarbuda -"AR" // Argentina -"AM" // Armenia -"AW" // Aruba -"AU" // Australia -"AT" // Austria -"AZ" // Azerbaijan -"BS" // Bahamas -"BH" // Bahrain -"BD" // Bangladesh -"BB" // Barbados -"BY" // Belarus -"BE" // Belgium -"BZ" // Belize -"BJ" // Benin -"BM" // Bermuda -"BT" // Bhutan -"BO" // Bolivia -"BA" // BosniaAndHerzegowina -"BW" // Botswana -"BV" // BouvetIsland -"BR" // Brazil -"IO" // BritishIndianOceanTerritory -"BN" // BruneiDarussalam -"BG" // Bulgaria -"BF" // BurkinaFaso -"BI" // Burundi -"KH" // Cambodia -"CM" // Cameroon -"CA" // Canada -"CV" // CapeVerde -"KY" // CaymanIslands -"CF" // CentralAfricanRepublic -"TD" // Chad -"CL" // Chile -"CN" // China -"CX" // ChristmasIsland -"CC" // CocosIslands -"CO" // Colombia -"KM" // Comoros -"CD" // DemocraticRepublicOfCongo -"CG" // PeoplesRepublicOfCongo -"CK" // CookIslands -"CR" // CostaRica -"CI" // IvoryCoast -"HR" // Croatia -"CU" // Cuba -"CY" // Cyprus -"CZ" // CzechRepublic -"DK" // Denmark -"DJ" // Djibouti -"DM" // Dominica -"DO" // DominicanRepublic -"TL" // EastTimor -"EC" // Ecuador -"EG" // Egypt -"SV" // ElSalvador -"GQ" // EquatorialGuinea -"ER" // Eritrea -"EE" // Estonia -"ET" // Ethiopia -"FK" // FalklandIslands -"FO" // FaroeIslands -"FJ" // Fiji -"FI" // Finland -"FR" // France -"FX" // MetropolitanFrance -"GF" // FrenchGuiana -"PF" // FrenchPolynesia -"TF" // FrenchSouthernTerritories -"GA" // Gabon -"GM" // Gambia -"GE" // Georgia -"DE" // Germany -"GH" // Ghana -"GI" // Gibraltar -"GR" // Greece -"GL" // Greenland -"GD" // Grenada -"GP" // Guadeloupe -"GU" // Guam -"GT" // Guatemala -"GN" // Guinea -"GW" // GuineaBissau -"GY" // Guyana -"HT" // Haiti -"HM" // HeardAndMcDonaldIslands -"HN" // Honduras -"HK" // HongKong -"HU" // Hungary -"IS" // Iceland -"IN" // India -"ID" // Indonesia -"IR" // Iran -"IQ" // Iraq -"IE" // Ireland -"IL" // Israel -"IT" // Italy -"JM" // Jamaica -"JP" // Japan -"JO" // Jordan -"KZ" // Kazakhstan -"KE" // Kenya -"KI" // Kiribati -"KP" // DemocraticRepublicOfKorea -"KR" // RepublicOfKorea -"KW" // Kuwait -"KG" // Kyrgyzstan -"LA" // Lao -"LV" // Latvia -"LB" // Lebanon -"LS" // Lesotho -"LR" // Liberia -"LY" // LibyanArabJamahiriya -"LI" // Liechtenstein -"LT" // Lithuania -"LU" // Luxembourg -"MO" // Macau -"MK" // Macedonia -"MG" // Madagascar -"MW" // Malawi -"MY" // Malaysia -"MV" // Maldives -"ML" // Mali -"MT" // Malta -"MH" // MarshallIslands -"MQ" // Martinique -"MR" // Mauritania -"MU" // Mauritius -"YT" // Mayotte -"MX" // Mexico -"FM" // Micronesia -"MD" // Moldova -"MC" // Monaco -"MN" // Mongolia -"MS" // Montserrat -"MA" // Morocco -"MZ" // Mozambique -"MM" // Myanmar -"NA" // Namibia -"NR" // Nauru -"NP" // Nepal -"NL" // Netherlands -"AN" // NetherlandsAntilles -"NC" // NewCaledonia -"NZ" // NewZealand -"NI" // Nicaragua -"NE" // Niger -"NG" // Nigeria -"NU" // Niue -"NF" // NorfolkIsland -"MP" // NorthernMarianaIslands -"NO" // Norway -"OM" // Oman -"PK" // Pakistan -"PW" // Palau -"PS" // PalestinianTerritory -"PA" // Panama -"PG" // PapuaNewGuinea -"PY" // Paraguay -"PE" // Peru -"PH" // Philippines -"PN" // Pitcairn -"PL" // Poland -"PT" // Portugal -"PR" // PuertoRico -"QA" // Qatar -"RE" // Reunion -"RO" // Romania -"RU" // RussianFederation -"RW" // Rwanda -"KN" // SaintKittsAndNevis -"LC" // StLucia -"VC" // StVincentAndTheGrenadines -"WS" // Samoa -"SM" // SanMarino -"ST" // SaoTomeAndPrincipe -"SA" // SaudiArabia -"SN" // Senegal -"SC" // Seychelles -"SL" // SierraLeone -"SG" // Singapore -"SK" // Slovakia -"SI" // Slovenia -"SB" // SolomonIslands -"SO" // Somalia -"ZA" // SouthAfrica -"GS" // SouthGeorgiaAndTheSouthSandwichIslands -"ES" // Spain -"LK" // SriLanka -"SH" // StHelena -"PM" // StPierreAndMiquelon -"SD" // Sudan -"SR" // Suriname -"SJ" // SvalbardAndJanMayenIslands -"SZ" // Swaziland -"SE" // Sweden -"CH" // Switzerland -"SY" // SyrianArabRepublic -"TW" // Taiwan -"TJ" // Tajikistan -"TZ" // Tanzania -"TH" // Thailand -"TG" // Togo -"TK" // Tokelau -"TO" // Tonga -"TT" // TrinidadAndTobago -"TN" // Tunisia -"TR" // Turkey -"TM" // Turkmenistan -"TC" // TurksAndCaicosIslands -"TV" // Tuvalu -"UG" // Uganda -"UA" // Ukraine -"AE" // UnitedArabEmirates -"GB" // UnitedKingdom -"US" // UnitedStates -"UM" // UnitedStatesMinorOutlyingIslands -"UY" // Uruguay -"UZ" // Uzbekistan -"VU" // Vanuatu -"VA" // VaticanCityState -"VE" // Venezuela -"VN" // VietNam -"VG" // BritishVirginIslands -"VI" // USVirginIslands -"WF" // WallisAndFutunaIslands -"EH" // WesternSahara -"YE" // Yemen -"YU" // Yugoslavia -"ZM" // Zambia -"ZW" // Zimbabwe -; - -static TQLocale::Language codeToLanguage(const TQString &code) -{ - if (code.length() != 2) - return TQLocale::C; - - ushort uc1 = code.unicode()[0].unicode(); - ushort uc2 = code.unicode()[1].unicode(); - - const char *c = language_code_list; - for (; *c != 0; c += 2) { - if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) - return (TQLocale::Language) ((c - language_code_list)/2); - } - - return TQLocale::C; -} - -static TQLocale::Country codeToCountry(const TQString &code) -{ - if (code.length() != 2) - return TQLocale::AnyCountry; - - ushort uc1 = code.unicode()[0].unicode(); - ushort uc2 = code.unicode()[1].unicode(); - - const char *c = country_code_list; - for (; *c != 0; c += 2) { - if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) - return (TQLocale::Country) ((c - country_code_list)/2); - } - - return TQLocale::AnyCountry; -} - -static TQString languageToCode(TQLocale::Language language) -{ - if (language == TQLocale::C) - return "C"; - - TQString code; - code.setLength(2); - const char *c = language_code_list + 2*(uint)language; - code[0] = c[0]; - code[1] = c[1]; - return code; -} - -static TQString countryToCode(TQLocale::Country country) -{ - if (country == TQLocale::AnyCountry) - return TQString::null; - - TQString code; - code.setLength(2); - const char *c = country_code_list + 2*(uint)country; - code[0] = c[0]; - code[1] = c[1]; - return code; -} - -const TQLocalePrivate *TQLocale::default_d = 0; - -TQString TQLocalePrivate::infinity() const -{ - return TQString::fromLatin1("inf"); -} - -TQString TQLocalePrivate::nan() const -{ - return TQString::fromLatin1("nan"); -} - -#if defined(Q_OS_WIN) -/* Win95 doesn't have a function to return the ISO lang/country name of the user's locale. - Instead it can return a "Windows code". This maps windows codes to ISO country names. */ - -struct WindowsToISOListElt { - int windows_code; - char iso_name[6]; -}; - -static const WindowsToISOListElt windows_to_iso_list[] = { - { 0x0401, "ar_SA" }, - { 0x0402, "bg\0 " }, - { 0x0403, "ca\0 " }, - { 0x0404, "zh_TW" }, - { 0x0405, "cs\0 " }, - { 0x0406, "da\0 " }, - { 0x0407, "de\0 " }, - { 0x0408, "el\0 " }, - { 0x0409, "en_US" }, - { 0x040a, "es\0 " }, - { 0x040b, "fi\0 " }, - { 0x040c, "fr\0 " }, - { 0x040d, "he\0 " }, - { 0x040e, "hu\0 " }, - { 0x040f, "is\0 " }, - { 0x0410, "it\0 " }, - { 0x0411, "ja\0 " }, - { 0x0412, "ko\0 " }, - { 0x0413, "nl\0 " }, - { 0x0414, "no\0 " }, - { 0x0415, "pl\0 " }, - { 0x0416, "pt_BR" }, - { 0x0418, "ro\0 " }, - { 0x0419, "ru\0 " }, - { 0x041a, "hr\0 " }, - { 0x041c, "sq\0 " }, - { 0x041d, "sv\0 " }, - { 0x041e, "th\0 " }, - { 0x041f, "tr\0 " }, - { 0x0420, "ur\0 " }, - { 0x0421, "in\0 " }, - { 0x0422, "uk\0 " }, - { 0x0423, "be\0 " }, - { 0x0425, "et\0 " }, - { 0x0426, "lv\0 " }, - { 0x0427, "lt\0 " }, - { 0x0429, "fa\0 " }, - { 0x042a, "vi\0 " }, - { 0x042d, "eu\0 " }, - { 0x042f, "mk\0 " }, - { 0x0436, "af\0 " }, - { 0x0438, "fo\0 " }, - { 0x0439, "hi\0 " }, - { 0x043e, "ms\0 " }, - { 0x0458, "mt\0 " }, - { 0x0801, "ar_IQ" }, - { 0x0804, "zh_CN" }, - { 0x0807, "de_CH" }, - { 0x0809, "en_GB" }, - { 0x080a, "es_MX" }, - { 0x080c, "fr_BE" }, - { 0x0810, "it_CH" }, - { 0x0812, "ko\0 " }, - { 0x0813, "nl_BE" }, - { 0x0814, "no\0 " }, - { 0x0816, "pt\0 " }, - { 0x081a, "sr\0 " }, - { 0x081d, "sv_FI" }, - { 0x0c01, "ar_EG" }, - { 0x0c04, "zh_HK" }, - { 0x0c07, "de_AT" }, - { 0x0c09, "en_AU" }, - { 0x0c0a, "es\0 " }, - { 0x0c0c, "fr_CA" }, - { 0x0c1a, "sr\0 " }, - { 0x1001, "ar_LY" }, - { 0x1004, "zh_SG" }, - { 0x1007, "de_LU" }, - { 0x1009, "en_CA" }, - { 0x100a, "es_GT" }, - { 0x100c, "fr_CH" }, - { 0x1401, "ar_DZ" }, - { 0x1407, "de_LI" }, - { 0x1409, "en_NZ" }, - { 0x140a, "es_CR" }, - { 0x140c, "fr_LU" }, - { 0x1801, "ar_MA" }, - { 0x1809, "en_IE" }, - { 0x180a, "es_PA" }, - { 0x1c01, "ar_TN" }, - { 0x1c09, "en_ZA" }, - { 0x1c0a, "es_DO" }, - { 0x2001, "ar_OM" }, - { 0x2009, "en_JM" }, - { 0x200a, "es_VE" }, - { 0x2401, "ar_YE" }, - { 0x2409, "en\0 " }, - { 0x240a, "es_CO" }, - { 0x2801, "ar_SY" }, - { 0x2809, "en_BZ" }, - { 0x280a, "es_PE" }, - { 0x2c01, "ar_JO" }, - { 0x2c09, "en_TT" }, - { 0x2c0a, "es_AR" }, - { 0x3001, "ar_LB" }, - { 0x300a, "es_EC" }, - { 0x3401, "ar_KW" }, - { 0x340a, "es_CL" }, - { 0x3801, "ar_AE" }, - { 0x380a, "es_UY" }, - { 0x3c01, "ar_BH" }, - { 0x3c0a, "es_PY" }, - { 0x4001, "ar_QA" }, - { 0x400a, "es_BO" }, - { 0x440a, "es_SV" }, - { 0x480a, "es_HN" }, - { 0x4c0a, "es_NI" }, - { 0x500a, "es_PR" } -}; - -static const int windows_to_iso_count - = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt); - -static const char *winLangCodeToIsoName(int code) -{ - int cmp = code - windows_to_iso_list[0].windows_code; - if (cmp < 0) - return 0; - - if (cmp == 0) - return windows_to_iso_list[0].iso_name; - - int begin = 0; - int end = windows_to_iso_count; - - while (end - begin > 1) { - uint mid = (begin + end)/2; - - const WindowsToISOListElt *elt = windows_to_iso_list + mid; - int cmp = code - elt->windows_code; - if (cmp < 0) - end = mid; - else if (cmp > 0) - begin = mid; - else - return elt->iso_name; - } - - return 0; - -} -#endif // Q_OS_WIN - -const char* TQLocalePrivate::systemLocaleName() -{ - static TQCString lang; - lang = getenv( "LANG" ); - -#if defined( Q_OS_MAC ) - if ( !lang.isEmpty() ) - return lang; - - char mac_ret[255]; - if(!LocaleRefGetPartString(NULL, kLocaleLanguageMask | kLocaleRegionMask, 255, mac_ret)) - lang = mac_ret; -#endif - -#if defined(TQ_WS_WIN) - if ( !lang.isEmpty() ) { - long id = 0; - bool ok = false; - id = qstrtoll(lang.data(), 0, 0, &ok); - if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) - return lang; - else - return winLangCodeToIsoName( (int)id ); - } - - if (qWinVersion() == TQt::WV_95) { - lang = winLangCodeToIsoName(GetUserDefaultLangID()); - } else { - QT_WA( { - wchar_t out[256]; - TQString language; - TQString sublanguage; - if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME , out, 255 ) ) - language = TQString::fromUcs2( (ushort*)out ); - if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) - sublanguage = TQString::fromUcs2( (ushort*)out ).lower(); - lang = language; - if ( sublanguage != language && !sublanguage.isEmpty() ) - lang += "_" + sublanguage.upper(); - } , { - char out[256]; - TQString language; - TQString sublanguage; - if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, out, 255 ) ) - language = TQString::fromLocal8Bit( out ); - if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) - sublanguage = TQString::fromLocal8Bit( out ).lower(); - lang = language; - if ( sublanguage != language && !sublanguage.isEmpty() ) - lang += "_" + sublanguage.upper(); - } ); - } -#endif - if ( lang.isEmpty() ) - lang = "C"; - - return lang; -} - -static const TQLocalePrivate *findLocale(TQLocale::Language language, - TQLocale::Country country) -{ - unsigned language_id = (unsigned)language; - unsigned country_id = (unsigned)country; - - uint idx = locale_index[language_id]; - - const TQLocalePrivate *d = locale_data + idx; - - if (idx == 0) // default language has no associated country - return d; - - if (country == TQLocale::AnyCountry) - return d; - - Q_ASSERT(d->languageId() == language_id); - - while (d->languageId() == language_id - && d->countryId() != country_id) - ++d; - - if (d->countryId() == country_id - && d->languageId() == language_id) - return d; - - return locale_data + idx; -} - -/*! - \class TQLocale - \brief The TQLocale class converts between numbers and their - string representations in various languages. - - \reentrant - \ingroup text - - It is initialized with a country/language pair in its constructor - and offers number-to-string and string-to-number conversion - functions simmilar to those in TQString. - - \code - TQLocale egyptian(TQLocale::Arabic, TQLocale::Egypt); - TQString s1 = egyptian.toString(1.571429E+07, 'e'); - TQString s2 = egyptian.toString(10); - - double d = egyptian.toDouble(s1); - int s2 = egyptian.toInt(s2); - \endcode - - TQLocale supports the concept of a default locale, which is - determined from the system's locale settings at application - startup. The default locale can be changed by calling the - static member setDefault(). The default locale has the - following effects: - - \list - \i If a TQLocale object is constructed with the default constructor, - it will use the default locale's settings. - \i TQString::toDouble() interprets the string according to the default - locale. If this fails, it falls back on the "C" locale. - \i TQString::arg() uses the default locale to format a number when - its position specifier in the format string contains an 'L', - e.g. "%L1". - \endlist - - \code - TQLocale::setDefault(TQLocale(TQLocale::Hebrew, TQLocale::Israel)); - TQLocale hebrew; // Constructs a default TQLocale - TQString s1 = hebrew.toString(15714.3, 'e'); - - bool ok; - double d; - - TQLocale::setDefault(TQLocale::C); - d = TQString( "1234,56" ).toDouble(&ok); // ok == false - d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 - - TQLocale::setDefault(TQLocale::German); - d = TQString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56 - d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 - - TQLocale::setDefault(TQLocale(TQLocale::English, TQLocale::UnitedStates)); - str = TQString( "%1 %L2 %L3" ) - .arg( 12345 ) - .arg( 12345 ) - .arg( 12345, 0, 16 ); - // str == "12345 12,345 3039" - \endcode - - When a language/country pair is specified in the constructor, one - of three things can happen: - - \list - \i If the language/country pair is found in the database, it is used. - \i If the language is found but the country is not, or if the country - is \c AnyCountry, the language is used with the most - appropriate available country (for example, Germany for German), - \i If neither the language nor the country are found, TQLocale - defaults to the default locale (see setDefault()). - \endlist - - The "C" locale is identical to English/UnitedStates. - - Use language() and country() to determine the actual language and - country values used. - - An alternative method for constructing a TQLocale object is by - specifying the locale name. - - \code - TQLocale korean("ko"); - TQLocale swiss("de_CH"); - \endcode - - This constructor converts the locale name to a language/country - pair; it does not use the system locale database. - - All the methods in TQLocale, with the exception of setDefault(), - are reentrant. - - \sa TQString::toDouble() TQString::arg() - - The double-to-string and string-to-double conversion functions are - covered by the following licenses: - - \legalese - - Copyright (c) 1991 by AT&T. - - Permission to use, copy, modify, and distribute this software for any - purpose without fee is hereby granted, provided that this entire notice - is included in all copies of any software which is or includes a copy - or modification of this software and in all copies of the supporting - documentation for such software. - - THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY - REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - - This product includes software developed by the University of - California, Berkeley and its contributors. -*/ - -/*! - \enum TQLocale::Language - - This enumerated type is used to specify a language. - - \value C Identical to English/UnitedStates - \value Abkhazian - \value Afan - \value Afar - \value Afrikaans - \value Albanian - \value Amharic - \value Arabic - \value Armenian - \value Assamese - \value Aymara - \value Azerbaijani - \value Bashkir - \value Basque - \value Bengali - \value Bhutani - \value Bihari - \value Bislama - \value Breton - \value Bulgarian - \value Burmese - \value Byelorussian - \value Cambodian - \value Catalan - \value Chinese - \value Corsican - \value Croatian - \value Czech - \value Danish - \value Dutch - \value English - \value Esperanto - \value Estonian - \value Faroese - \value FijiLanguage - \value Finnish - \value French - \value Frisian - \value Gaelic - \value Galician - \value Georgian - \value German - \value Greek - \value Greenlandic - \value Guarani - \value Gujarati - \value Hausa - \value Hebrew - \value Hindi - \value Hungarian - \value Icelandic - \value Indonesian - \value Interlingua - \value Interlingue - \value Inuktitut - \value Inupiak - \value Irish - \value Italian - \value Japanese - \value Javanese - \value Kannada - \value Kashmiri - \value Kazakh - \value Kinyarwanda - \value Kirghiz - \value Korean - \value Kurdish - \value Kurundi - \value Laothian - \value Latin - \value Latvian - \value Lingala - \value Lithuanian - \value Macedonian - \value Malagasy - \value Malay - \value Malayalam - \value Maltese - \value Maori - \value Marathi - \value Moldavian - \value Mongolian - \value NauruLanguage - \value Nepali - \value Norwegian - \value Occitan - \value Oriya - \value Pashto - \value Persian - \value Polish - \value Portuguese - \value Punjabi - \value Quechua - \value RhaetoRomance - \value Romanian - \value Russian - \value Samoan - \value Sangho - \value Sanskrit - \value Serbian - \value SerboCroatian - \value Sesotho - \value Setswana - \value Shona - \value Sindhi - \value Singhalese - \value Siswati - \value Slovak - \value Slovenian - \value Somali - \value Spanish - \value Sundanese - \value Swahili - \value Swedish - \value Tagalog - \value Tajik - \value Tamil - \value Tatar - \value Telugu - \value Thai - \value Tibetan - \value Tigrinya - \value TongaLanguage - \value Tsonga - \value Turkish - \value Turkmen - \value Twi - \value Uigur - \value Ukrainian - \value Urdu - \value Uzbek - \value Vietnamese - \value Volapuk - \value Welsh - \value Wolof - \value Xhosa - \value Yiddish - \value Yoruba - \value Zhuang - \value Zulu -*/ - -/*! - \enum TQLocale::Country - - This enumerated type is used to specify a country. - - \value AnyCountry - \value Afghanistan - \value Albania - \value Algeria - \value AmericanSamoa - \value Andorra - \value Angola - \value Anguilla - \value Antarctica - \value AntiguaAndBarbuda - \value Argentina - \value Armenia - \value Aruba - \value Australia - \value Austria - \value Azerbaijan - \value Bahamas - \value Bahrain - \value Bangladesh - \value Barbados - \value Belarus - \value Belgium - \value Belize - \value Benin - \value Bermuda - \value Bhutan - \value Bolivia - \value BosniaAndHerzegowina - \value Botswana - \value BouvetIsland - \value Brazil - \value BritishIndianOceanTerritory - \value BruneiDarussalam - \value Bulgaria - \value BurkinaFaso - \value Burundi - \value Cambodia - \value Cameroon - \value Canada - \value CapeVerde - \value CaymanIslands - \value CentralAfricanRepublic - \value Chad - \value Chile - \value China - \value ChristmasIsland - \value CocosIslands - \value Colombia - \value Comoros - \value DemocraticRepublicOfCongo - \value PeoplesRepublicOfCongo - \value CookIslands - \value CostaRica - \value IvoryCoast - \value Croatia - \value Cuba - \value Cyprus - \value CzechRepublic - \value Denmark - \value Djibouti - \value Dominica - \value DominicanRepublic - \value EastTimor - \value Ecuador - \value Egypt - \value ElSalvador - \value EquatorialGuinea - \value Eritrea - \value Estonia - \value Ethiopia - \value FalklandIslands - \value FaroeIslands - \value FijiCountry - \value Finland - \value France - \value MetropolitanFrance - \value FrenchGuiana - \value FrenchPolynesia - \value FrenchSouthernTerritories - \value Gabon - \value Gambia - \value Georgia - \value Germany - \value Ghana - \value Gibraltar - \value Greece - \value Greenland - \value Grenada - \value Guadeloupe - \value Guam - \value Guatemala - \value Guinea - \value GuineaBissau - \value Guyana - \value Haiti - \value HeardAndMcDonaldIslands - \value Honduras - \value HongKong - \value Hungary - \value Iceland - \value India - \value Indonesia - \value Iran - \value Iraq - \value Ireland - \value Israel - \value Italy - \value Jamaica - \value Japan - \value Jordan - \value Kazakhstan - \value Kenya - \value Kiribati - \value DemocraticRepublicOfKorea - \value RepublicOfKorea - \value Kuwait - \value Kyrgyzstan - \value Lao - \value Latvia - \value Lebanon - \value Lesotho - \value Liberia - \value LibyanArabJamahiriya - \value Liechtenstein - \value Lithuania - \value Luxembourg - \value Macau - \value Macedonia - \value Madagascar - \value Malawi - \value Malaysia - \value Maldives - \value Mali - \value Malta - \value MarshallIslands - \value Martinique - \value Mauritania - \value Mauritius - \value Mayotte - \value Mexico - \value Micronesia - \value Moldova - \value Monaco - \value Mongolia - \value Montserrat - \value Morocco - \value Mozambique - \value Myanmar - \value Namibia - \value NauruCountry - \value Nepal - \value Netherlands - \value NetherlandsAntilles - \value NewCaledonia - \value NewZealand - \value Nicaragua - \value Niger - \value Nigeria - \value Niue - \value NorfolkIsland - \value NorthernMarianaIslands - \value Norway - \value Oman - \value Pakistan - \value Palau - \value PalestinianTerritory - \value Panama - \value PapuaNewGuinea - \value Paraguay - \value Peru - \value Philippines - \value Pitcairn - \value Poland - \value Portugal - \value PuertoRico - \value Qatar - \value Reunion - \value Romania - \value RussianFederation - \value Rwanda - \value SaintKittsAndNevis - \value StLucia - \value StVincentAndTheGrenadines - \value Samoa - \value SanMarino - \value SaoTomeAndPrincipe - \value SaudiArabia - \value Senegal - \value Seychelles - \value SierraLeone - \value Singapore - \value Slovakia - \value Slovenia - \value SolomonIslands - \value Somalia - \value SouthAfrica - \value SouthGeorgiaAndTheSouthSandwichIslands - \value Spain - \value SriLanka - \value StHelena - \value StPierreAndMiquelon - \value Sudan - \value Suriname - \value SvalbardAndJanMayenIslands - \value Swaziland - \value Sweden - \value Switzerland - \value SyrianArabRepublic - \value Taiwan - \value Tajikistan - \value Tanzania - \value Thailand - \value Togo - \value Tokelau - \value TongaCountry - \value TrinidadAndTobago - \value Tunisia - \value Turkey - \value Turkmenistan - \value TurksAndCaicosIslands - \value Tuvalu - \value Uganda - \value Ukraine - \value UnitedArabEmirates - \value UnitedKingdom - \value UnitedStates - \value UnitedStatesMinorOutlyingIslands - \value Uruguay - \value Uzbekistan - \value Vanuatu - \value VaticanCityState - \value Venezuela - \value VietNam - \value BritishVirginIslands - \value USVirginIslands - \value WallisAndFutunaIslands - \value WesternSahara - \value Yemen - \value Yugoslavia - \value Zambia - \value Zimbabwe -*/ - -/*! - Constructs a TQLocale object with the specified \a name, - which has the format - "language[_country][.codeset][@modifier]" or "C", where: - - \list - \i language is a lowercase, two-letter, ISO 639 language code, - \i territory is an uppercase, two-letter, ISO 3166 country code, - \i and codeset and modifier are ignored. - \endlist - - If the string violates the locale format, or language is not - a valid ISO 369 code, the "C" locale is used instead. If country - is not present, or is not a valid ISO 3166 code, the most - appropriate country is chosen for the specified language. - - The language and country codes are converted to their respective - \c Language and \c Country enums. After this conversion is - performed the constructor behaves exactly like TQLocale(Country, - Language). - - This constructor is much slower than TQLocale(Country, Language). - - \sa name() -*/ - -TQLocale::TQLocale(const TQString &name) -{ - Language lang = C; - Country cntry = AnyCountry; - - uint l = name.length(); - - do { - if (l < 2) - break; - - const TQChar *uc = name.unicode(); - if (l > 2 - && uc[2] != '_' - && uc[2] != '.' - && uc[2] != '@') - break; - - lang = codeToLanguage(name.mid(0, 2)); - if (lang == C) - break; - - if (l == 2 || uc[2] == '.' || uc[2] == '@') - break; - - // we have uc[2] == '_' - if (l < 5) - break; - - if (l > 5 && uc[5] != '.' && uc[5] != '@') - break; - - cntry = codeToCountry(name.mid(3, 2)); - } while (FALSE); - - d = findLocale(lang, cntry); -} - -/*! - Constructs a TQLocale object initialized with the default locale. - - \sa setDefault() -*/ - -TQLocale::TQLocale() -{ - if (default_d == 0) - default_d = system().d; - - d = default_d; -} - -/*! - Constructs a TQLocale object with the specified \a language and \a - country. - - \list - \i If the language/country pair is found in the database, it is used. - \i If the language is found but the country is not, or if the country - is \c AnyCountry, the language is used with the most - appropriate available country (for example, Germany for German), - \i If neither the language nor the country are found, TQLocale - defaults to the default locale (see setDefault()). - \endlist - - The language and country that are actually used can be queried - using language() and country(). - - \sa setDefault() language() country() -*/ - -TQLocale::TQLocale(Language language, Country country) -{ - d = findLocale(language, country); - - // If not found, should default to system - if (d->languageId() == TQLocale::C && language != TQLocale::C) { - if (default_d == 0) - default_d = system().d; - - d = default_d; - } -} - -/*! - Constructs a TQLocale object as a copy of \a other. -*/ - -TQLocale::TQLocale(const TQLocale &other) -{ - d = other.d; -} - -/*! - Assigns \a other to this TQLocale object and returns a reference - to this TQLocale object. -*/ - -TQLocale &TQLocale::operator=(const TQLocale &other) -{ - d = other.d; - return *this; -} - -/*! - \nonreentrant - - Sets the global default locale to \a locale. These - values are used when a TQLocale object is constructed with - no arguments. If this function is not called, the system's - locale is used. - - \warning In a multithreaded application, the default locale - should be set at application startup, before any non-GUI threads - are created. - - \sa system() c() -*/ - -void TQLocale::setDefault(const TQLocale &locale) -{ - default_d = locale.d; -} - -/*! - Returns the language of this locale. - - \sa TQLocale() -*/ -TQLocale::Language TQLocale::language() const -{ - return (Language)d->languageId(); -} - -/*! - Returns the country of this locale. - - \sa TQLocale() -*/ -TQLocale::Country TQLocale::country() const -{ - return (Country)d->countryId(); -} - -/*! - Returns the language and country of this locale as a - string of the form "language_country", where - language is a lowercase, two-letter ISO 639 language code, - and country is an uppercase, two-letter ISO 3166 country code. - - \sa TQLocale() -*/ - -TQString TQLocale::name() const -{ - Language l = language(); - - TQString result = languageToCode(l); - - if (l == C) - return result; - - Country c = country(); - if (c == AnyCountry) - return result; - - result.append('_'); - result.append(countryToCode(c)); - - return result; -} - -/*! - Returns a TQString containing the name of \a language. -*/ - -TQString TQLocale::languageToString(Language language) -{ - if ((uint)language > (uint)TQLocale::LastLanguage) - return "Unknown"; - return language_name_list + language_name_index[(uint)language]; -} - -/*! - Returns a TQString containing the name of \a country. -*/ - -TQString TQLocale::countryToString(Country country) -{ - if ((uint)country > (uint)TQLocale::LastCountry) - return "Unknown"; - return country_name_list + country_name_index[(uint)country]; -} - -/*! - Returns the short int represented by the localized string \a s, or - 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -short TQLocale::toShort(const TQString &s, bool *ok) const -{ - TQ_LLONG i = toLongLong(s, ok); - if (i < SHRT_MIN || i > SHRT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (short) i; -} - -/*! - Returns the unsigned short int represented by the localized string - \a s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -ushort TQLocale::toUShort(const TQString &s, bool *ok) const -{ - TQ_ULLONG i = toULongLong(s, ok); - if (i > USHRT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (ushort) i; -} - -/*! - Returns the int represented by the localized string \a s, or 0 if - the conversion failed. - - If \a ok is not 0, reports failure by setting *ok to false and - success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -int TQLocale::toInt(const TQString &s, bool *ok) const -{ - TQ_LLONG i = toLongLong(s, ok); - if (i < INT_MIN || i > INT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (int) i; -} - -/*! - Returns the unsigned int represented by the localized string \a s, - or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -uint TQLocale::toUInt(const TQString &s, bool *ok) const -{ - TQ_ULLONG i = toULongLong(s, ok); - if (i > UINT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (uint) i; -} - -/*! - Returns the long int represented by the localized string \a s, or - 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -TQ_LONG TQLocale::toLong(const TQString &s, bool *ok) const -{ - TQ_LLONG i = toLongLong(s, ok); - if (i < LONG_MIN || i > LONG_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (TQ_LONG) i; -} - -/*! - Returns the unsigned long int represented by the localized string - \a s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -TQ_ULONG TQLocale::toULong(const TQString &s, bool *ok) const -{ - TQ_ULLONG i = toULongLong(s, ok); - if (i > ULONG_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (TQ_ULONG) i; -} - -/*! - Returns the long long int represented by the localized string \a - s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - - -TQ_LLONG TQLocale::toLongLong(const TQString &s, bool *ok) const -{ - return d->stringToLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); -} - -/*! - Returns the unsigned long long int represented by the localized - string \a s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - - -TQ_ULLONG TQLocale::toULongLong(const TQString &s, bool *ok) const -{ - return d->stringToUnsLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); -} - -/*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -#define QT_MAX_FLOAT 3.4028234663852886e+38 - -float TQLocale::toFloat(const TQString &s, bool *ok) const -{ - bool myOk; - double d = toDouble(s, &myOk); - if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) { - if (ok != 0) - *ok = FALSE; - return 0.0; - } - if (ok != 0) - *ok = TRUE; - return (float) d; -} - -/*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - Unlike TQString::toDouble(), this function does not fall back to - the "C" locale if the string cannot be interpreted in this - locale. - - \code - bool ok; - double d; - - TQLocale c(TQLocale::C); - d = c.toDouble( "1234.56", &ok ); // ok == true, d == 1234.56 - d = c.toDouble( "1,234.56", &ok ); // ok == true, d == 1234.56 - d = c.toDouble( "1234,56", &ok ); // ok == false - - TQLocale german(TQLocale::German); - d = german.toDouble( "1234,56", &ok ); // ok == true, d == 1234.56 - d = german.toDouble( "1.234,56", &ok ); // ok == true, d == 1234.56 - d = german.toDouble( "1234.56", &ok ); // ok == false - - d = german.toDouble( "1.234", &ok ); // ok == true, d == 1234.0 - \endcode - - Notice that the last conversion returns 1234.0, because '.' is the - thousands group separator in the German locale. - - This function ignores leading and trailing whitespace. - - \sa toString() TQString::toDouble() -*/ - -double TQLocale::toDouble(const TQString &s, bool *ok) const -{ - return d->stringToDouble(s, ok, TQLocalePrivate::ParseGroupSeparators); -} - -/*! - Returns a localized string representation of \a i. - - \sa toLongLong() -*/ - -TQString TQLocale::toString(TQ_LLONG i) const -{ - return d->longLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); -} - -/*! - \overload - - \sa toULongLong() -*/ - -TQString TQLocale::toString(TQ_ULLONG i) const -{ - return d->unsLongLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); -} - -static bool qIsUpper(char c) -{ - return c >= 'A' && c <= 'Z'; -} - -static char qToLower(char c) -{ - if (c >= 'A' && c <= 'Z') - return c - 'A' + 'a'; - else - return c; -} - -/*! - \overload - - \a f and \a prec have the same meaning as in TQString::number(double, char, int). - - \sa toDouble() -*/ - -TQString TQLocale::toString(double i, char f, int prec) const -{ - TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal; - uint flags = 0; - - if (qIsUpper(f)) - flags = TQLocalePrivate::CapitalEorX; - f = qToLower(f); - - switch (f) { - case 'f': - form = TQLocalePrivate::DFDecimal; - break; - case 'e': - form = TQLocalePrivate::DFExponent; - break; - case 'g': - form = TQLocalePrivate::DFSignificantDigits; - break; - default: - break; - } - - flags |= TQLocalePrivate::ThousandsGroup; - return d->doubleToString(i, prec, form, -1, flags); -} - -/*! - \fn TQLocale TQLocale::c() - - Returns a TQLocale object initialized to the "C" locale. - - \sa system() -*/ - -/*! - Returns a TQLocale object initialized to the system locale. -*/ - -TQLocale TQLocale::system() -{ -#ifdef Q_OS_UNIX - const char *s = getenv("LC_NUMERIC"); - if (s == 0) - s = getenv("LC_ALL"); - if (s != 0) - return TQLocale(s); -#endif - return TQLocale(TQLocalePrivate::systemLocaleName()); -} - -/*! -\fn TQString TQLocale::toString(short i) const - -\overload - -\sa toShort() -*/ - -/*! -\fn TQString TQLocale::toString(ushort i) const - -\overload - -\sa toUShort() -*/ - -/*! -\fn TQString TQLocale::toString(int i) const - -\overload - -\sa toInt() -*/ - -/*! -\fn TQString TQLocale::toString(uint i) const - -\overload - -\sa toUInt() -*/ - -/*! -\fn TQString TQLocale::toString(TQ_LONG i) const - -\overload - -\sa toLong() -*/ - -/*! -\fn TQString TQLocale::toString(TQ_ULONG i) const - -\overload - -\sa toULong() -*/ - -/*! -\fn TQString TQLocale::toString(float i, char f = 'g', int prec = 6) const - -\overload - -\a f and \a prec have the same meaning as in TQString::number(double, char, int). - -\sa toDouble() -*/ - - -bool TQLocalePrivate::isDigit(TQChar d) const -{ - return zero().unicode() <= d.unicode() - && zero().unicode() + 10 > d.unicode(); -} - -static char digitToCLocale(TQChar zero, TQChar d) -{ - if (zero.unicode() <= d.unicode() - && zero.unicode() + 10 > d.unicode()) - return '0' + d.unicode() - zero.unicode(); - - tqWarning("TQLocalePrivate::digitToCLocale(): bad digit: row=%d, cell=%d", d.row(), d.cell()); - return TQChar(0); -} - -static TQString qulltoa(TQ_ULLONG l, int base, const TQLocalePrivate &locale) -{ - TQChar buff[65]; // length of MAX_ULLONG in base 2 - TQChar *p = buff + 65; - - if (base != 10 || locale.zero().unicode() == '0') { - while (l != 0) { - int c = l % base; - - --p; - - if (c < 10) - *p = '0' + c; - else - *p = c - 10 + 'a'; - - l /= base; - } - } - else { - while (l != 0) { - int c = l % base; - - *(--p) = locale.zero().unicode() + c; - - l /= base; - } - } - - return TQString(p, 65 - (p - buff)); -} - -static TQString qlltoa(TQ_LLONG l, int base, const TQLocalePrivate &locale) -{ - return qulltoa(l < 0 ? -l : l, base, locale); -} - -enum PrecisionMode { - PMDecimalDigits = 0x01, - PMSignificantDigits = 0x02, - PMChopTrailingZeros = 0x03 -}; - -static TQString &decimalForm(TQString &digits, int decpt, uint precision, - PrecisionMode pm, - bool always_show_decpt, - bool thousands_group, - const TQLocalePrivate &locale) -{ - if (decpt < 0) { - for (int i = 0; i < -decpt; ++i) - digits.prepend(locale.zero()); - decpt = 0; - } - else if ((uint)decpt > digits.length()) { - for (uint i = digits.length(); i < (uint)decpt; ++i) - digits.append(locale.zero()); - } - - if (pm == PMDecimalDigits) { - uint decimal_digits = digits.length() - decpt; - for (uint i = decimal_digits; i < precision; ++i) - digits.append(locale.zero()); - } - else if (pm == PMSignificantDigits) { - for (uint i = digits.length(); i < precision; ++i) - digits.append(locale.zero()); - } - else { // pm == PMChopTrailingZeros - } - - if (always_show_decpt || (uint)decpt < digits.length()) - digits.insert(decpt, locale.decimal()); - - if (thousands_group) { - for (int i = decpt - 3; i > 0; i -= 3) - digits.insert(i, locale.group()); - } - - if (decpt == 0) - digits.prepend(locale.zero()); - - return digits; -} - -static TQString &exponentForm(TQString &digits, int decpt, uint precision, - PrecisionMode pm, - bool always_show_decpt, - const TQLocalePrivate &locale) -{ - int exp = decpt - 1; - - if (pm == PMDecimalDigits) { - for (uint i = digits.length(); i < precision + 1; ++i) - digits.append(locale.zero()); - } - else if (pm == PMSignificantDigits) { - for (uint i = digits.length(); i < precision; ++i) - digits.append(locale.zero()); - } - else { // pm == PMChopTrailingZeros - } - - if (always_show_decpt || digits.length() > 1) - digits.insert(1, locale.decimal()); - - digits.append(locale.exponential()); - digits.append(locale.longLongToString(exp, 2, 10, - -1, TQLocalePrivate::AlwaysShowSign)); - - return digits; -} - -static bool isZero(double d) -{ - uchar *ch = (uchar *)&d; - if (ByteOrder == BigEndian) { - return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]); - } else { - return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]); - } -} - -TQString TQLocalePrivate::doubleToString(double d, - int precision, - DoubleForm form, - int width, - unsigned flags) const -{ - if (precision == -1) - precision = 6; - if (width == -1) - width = 0; - - bool negative = FALSE; - bool special_number = FALSE; // nan, +/-inf - TQString num_str; - -#ifdef Q_OS_WIN - // Detect special numbers (nan, +/-inf) - if (qIsInf(d)) { - num_str = infinity(); - special_number = TRUE; - negative = d < 0; - } else if (qIsNan(d)) { - num_str = nan(); - special_number = TRUE; - } -#else - // Comparing directly to INFINITY gives weird results on some systems. - double tmp_infinity = INFINITY; - - // Detect special numbers (nan, +/-inf) - if (d == tmp_infinity || d == -tmp_infinity) { - num_str = infinity(); - special_number = TRUE; - negative = d < 0; - } else if (qIsNan(d)) { - num_str = nan(); - special_number = TRUE; - } -#endif - - // Handle normal numbers - if (!special_number) { - int decpt, sign; - TQString digits; - -#ifdef QT_QLOCALE_USES_FCVT -#ifdef TQT_THREAD_SUPPORT - static bool dummy_for_mutex; - TQMutex *fcvt_mutex = tqt_global_mutexpool ? tqt_global_mutexpool->get( &dummy_for_mutex ) : 0; -# define FCVT_LOCK if (fcvt_mutex) fcvt_mutex->lock() -# define FCVT_UNLOCK if (fcvt_mutex) fcvt_mutex->unlock() -#else -# define FCVT_LOCK -# define FCVT_UNLOCK -#endif - if (form == DFDecimal) { - FCVT_LOCK; - digits = fcvt(d, precision, &decpt, &sign); - FCVT_UNLOCK; - } else { - int pr = precision; - if (form == DFExponent) - ++pr; - else if (form == DFSignificantDigits && pr == 0) - pr = 1; - FCVT_LOCK; - digits = ecvt(d, pr, &decpt, &sign); - FCVT_UNLOCK; - - // Chop trailing zeros - if (digits.length() > 0) { - int last_nonzero_idx = digits.length() - 1; - while (last_nonzero_idx > 0 - && digits.unicode()[last_nonzero_idx] == '0') - --last_nonzero_idx; - digits.truncate(last_nonzero_idx + 1); - } - - } - -#else - int mode; - if (form == DFDecimal) - mode = 3; - else - mode = 2; - - /* This next bit is a bit quirky. In DFExponent form, the precision - is the number of digits after decpt. So that would suggest using - mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and - precision=0. So we get around this by using mode=2 and reasoning - that we want precision+1 significant digits, since the decimal - point in this mode is always after the first digit. */ - int pr = precision; - if (form == DFExponent) - ++pr; - - char *rve = 0; - char *buff = 0; - digits = qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff); - if (buff != 0) - free(buff); -#endif // QT_QLOCALE_USES_FCVT - - if (zero().unicode() != '0') { - for (uint i = 0; i < digits.length(); ++i) - digits.ref(i).unicode() += zero().unicode() - '0'; - } - - bool always_show_decpt = flags & Alternate; - switch (form) { - case DFExponent: { - num_str = exponentForm(digits, decpt, precision, PMDecimalDigits, - always_show_decpt, *this); - break; - } - case DFDecimal: { - num_str = decimalForm(digits, decpt, precision, PMDecimalDigits, - always_show_decpt, flags & ThousandsGroup, - *this); - break; - } - case DFSignificantDigits: { - PrecisionMode mode = (flags & Alternate) ? - PMSignificantDigits : PMChopTrailingZeros; - - if (decpt != (int)digits.length() && (decpt <= -4 || decpt > (int)precision)) - num_str = exponentForm(digits, decpt, precision, mode, - always_show_decpt, *this); - else - num_str = decimalForm(digits, decpt, precision, mode, - always_show_decpt, flags & ThousandsGroup, - *this); - break; - } - } - - negative = sign != 0 && !isZero(d); - } - - // pad with zeros. LeftAdjusted overrides this flag). Also, we don't - // pad special numbers - if (flags & TQLocalePrivate::ZeroPadded - && !(flags & TQLocalePrivate::LeftAdjusted) - && !special_number) { - int num_pad_chars = width - (int)num_str.length(); - // leave space for the sign - if (negative - || flags & TQLocalePrivate::AlwaysShowSign - || flags & TQLocalePrivate::BlankBeforePositive) - --num_pad_chars; - - for (int i = 0; i < num_pad_chars; ++i) - num_str.prepend(zero()); - } - - // add sign - if (negative) - num_str.prepend(minus()); - else if (flags & TQLocalePrivate::AlwaysShowSign) - num_str.prepend(plus()); - else if (flags & TQLocalePrivate::BlankBeforePositive) - num_str.prepend(' '); - - if (flags & TQLocalePrivate::CapitalEorX) - num_str = num_str.upper(); - - return num_str; -} - -TQString TQLocalePrivate::longLongToString(TQ_LLONG l, int precision, - int base, int width, - unsigned flags) const -{ - bool precision_not_specified = FALSE; - if (precision == -1) { - precision_not_specified = TRUE; - precision = 1; - } - - bool negative = l < 0; - if (base != 10) { - // these are not suported by sprintf for octal and hex - flags &= ~AlwaysShowSign; - flags &= ~BlankBeforePositive; - negative = FALSE; // neither are negative numbers - } - - TQString num_str; - if (base == 10) - num_str = qlltoa(l, base, *this); - else - num_str = qulltoa(l, base, *this); - - uint cnt_thousand_sep = 0; - if (flags & ThousandsGroup && base == 10) { - for (int i = (int)num_str.length() - 3; i > 0; i -= 3) { - num_str.insert(i, group()); - ++cnt_thousand_sep; - } - } - - for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - - if (flags & Alternate - && base == 8 - && (num_str.isEmpty() - || num_str[0].unicode() != '0')) - num_str.prepend('0'); - - // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds - // when precision is not specified in the format string - bool zero_padded = flags & ZeroPadded - && !(flags & LeftAdjusted) - && precision_not_specified; - - if (zero_padded) { - int num_pad_chars = width - (int)num_str.length(); - - // leave space for the sign - if (negative - || flags & AlwaysShowSign - || flags & BlankBeforePositive) - --num_pad_chars; - - // leave space for optional '0x' in hex form - if (base == 16 - && flags & Alternate - && l != 0) - num_pad_chars -= 2; - - for (int i = 0; i < num_pad_chars; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - } - - if (base == 16 - && flags & Alternate - && l != 0) - num_str.prepend("0x"); - - // add sign - if (negative) - num_str.prepend(minus()); - else if (flags & AlwaysShowSign) - num_str.prepend(base == 10 ? plus() : TQChar('+')); - else if (flags & BlankBeforePositive) - num_str.prepend(' '); - - if (flags & CapitalEorX) - num_str = num_str.upper(); - - return num_str; -} - -TQString TQLocalePrivate::unsLongLongToString(TQ_ULLONG l, int precision, - int base, int width, - unsigned flags) const -{ - bool precision_not_specified = FALSE; - if (precision == -1) { - precision_not_specified = TRUE; - precision = 1; - } - - TQString num_str = qulltoa(l, base, *this); - - uint cnt_thousand_sep = 0; - if (flags & ThousandsGroup && base == 10) { - for (int i = (int)num_str.length() - 3; i > 0; i -=3) { - num_str.insert(i, group()); - ++cnt_thousand_sep; - } - } - - for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - - if (flags & Alternate - && base == 8 - && (num_str.isEmpty() - || num_str[0].unicode() != '0')) - num_str.prepend('0'); - - // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds - // when precision is not specified in the format string - bool zero_padded = flags & ZeroPadded - && !(flags & LeftAdjusted) - && precision_not_specified; - - if (zero_padded) { - int num_pad_chars = width - (int)num_str.length(); - - // leave space for optional '0x' in hex form - if (base == 16 - && flags & Alternate - && l != 0) - num_pad_chars -= 2; - - for (int i = 0; i < num_pad_chars; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - } - - if (base == 16 - && flags & Alternate - && l != 0) - num_str.prepend("0x"); - - if (flags & CapitalEorX) - num_str = num_str.upper(); - - return num_str; -} - -static inline bool isLatin1Digit(const TQChar &c) -{ - return c.unicode() >= '0' && c.unicode() <= '9'; -} - -// Removes thousand-group separators, ie. the ',' in "1,234,567.89e-5" -bool TQLocalePrivate::removeGroupSeparators(TQString &num_str) const -{ - int group_cnt = 0; // counts number of group chars - int decpt_idx = -1; - - // Find the decimal point and check if there are any group chars - uint i = 0; - for (; i < num_str.length(); ++i) { - TQChar c = num_str.unicode()[i]; - - if (c.unicode() == ',') { - // check that there are digits before and after the separator - if (i == 0 || !isLatin1Digit(num_str.unicode()[i - 1])) - return FALSE; - if (i == num_str.length() + 1 || !isLatin1Digit(num_str.unicode()[i + 1])) - return FALSE; - ++group_cnt; - } - else if (c.unicode() == '.') { - // Fail if more than one decimal points - if (decpt_idx != -1) - return FALSE; - decpt_idx = i; - } else if (c.unicode() == 'e' || c.unicode() == 'E') { - // an 'e' or 'E' - if we have not encountered a decimal - // point, this is where it "is". - if (decpt_idx == -1) - decpt_idx = i; - } - } - - // If no group chars, we're done - if (group_cnt == 0) - return TRUE; - - // No decimal point means that it "is" at the end of the string - if (decpt_idx == -1) - decpt_idx = num_str.length(); - - i = 0; - while (i < num_str.length() && group_cnt > 0) { - TQChar c = num_str.unicode()[i]; - - if (c.unicode() == ',') { - // Don't allow group chars after the decimal point - if ((int)i > decpt_idx) - return FALSE; - - // Check that it is placed correctly relative to the decpt - if ((decpt_idx - i) % 4 != 0) - return FALSE; - - // Remove it - num_str.remove(i, 1); - - --group_cnt; - --decpt_idx; // adjust decpt_idx - } else { - // Check that we are not missing a separator - if ((int)i < decpt_idx && (decpt_idx - i) % 4 == 0) - return FALSE; - ++i; - } - } - - return TRUE; -} - -static void stripWhiteSpaceInPlace(TQString &s) -{ - uint i = 0; - while (i < s.length() && s.unicode()[i].isSpace()) - ++i; - if (i > 0) - s.remove(0, i); - - i = s.length(); - - if (i == 0) - return; - --i; - while (i > 0 && s.unicode()[i].isSpace()) - --i; - if (i + 1 < s.length()) - s.truncate(i + 1); -} - -/* - Converts a number in locale to its representation in the C locale. - Only has to guarantee that a string that is a correct representation of - a number will be converted. If junk is passed in, junk will be passed - out and the error will be detected during the actual conversion to a - number. We can't detect junk here, since we don't even know the base - of the number. -*/ -bool TQLocalePrivate::numberToCLocale(TQString &l_num, - GroupSeparatorMode group_sep_mode) const -{ - stripWhiteSpaceInPlace(l_num); - - if (l_num.isEmpty()) - return FALSE; - - for (uint idx = 0; idx < l_num.length(); ++idx) { - TQChar &c = l_num.ref(idx); - - if (isDigit(c)) - c = digitToCLocale(zero(), c); - else if (c == plus()) - c = '+'; - else if (c == minus()) - c = '-'; - else if (c == decimal()) - c = '.'; - else if (c == group()) - c = ','; - // In several languages group() is the char 0xA0, which looks like a space. - // People use a regular space instead of it and complain it doesn't work. - else if (group().unicode() == 0xA0 && c.unicode() == ' ') - c = ','; - else if (c == exponential() || c == exponential().upper()) - c = 'e'; - else if (c == list()) - c = ';'; - else if (c == percent()) - c = '%'; - else if (c.unicode() >= 'A' && c.unicode() <= 'Z') - c = c.lower(); - else if (c.unicode() >= 'a' && c.unicode() <= 'z') - ; // do nothing - else - return FALSE; - } - - if (group_sep_mode == ParseGroupSeparators - && !removeGroupSeparators(l_num)) - return FALSE; - - return TRUE; -} - -double TQLocalePrivate::stringToDouble(TQString num, - bool *ok, - GroupSeparatorMode group_sep_mode) const -{ - if (!numberToCLocale(num, group_sep_mode)) { - if (ok != 0) - *ok = FALSE; - return 0.0; - } - - if (ok != 0) - *ok = TRUE; - - if (num == "nan") - return NAN; - - if (num == "+inf" - || num == "inf") - return INFINITY; - - if (num == "-inf") - return -INFINITY; - - bool _ok; - const char *num_buff = num.latin1(); - -#ifdef QT_QLOCALE_USES_FCVT - char *endptr; - double d = strtod(num_buff, &endptr); - _ok = TRUE; -#else - const char *endptr; - double d = qstrtod(num_buff, &endptr, &_ok); -#endif - - if (!_ok || *endptr != '\0') { - if (ok != 0) - *ok = FALSE; - return 0.0; - } - else - return d; -} - -TQ_LLONG TQLocalePrivate::stringToLongLong(TQString num, int base, - bool *ok, - GroupSeparatorMode group_sep_mode) const -{ - if (!numberToCLocale(num, group_sep_mode)) { - if (ok != 0) - *ok = FALSE; - return 0; - } - - bool _ok; - const char *endptr; - const char *num_buff = num.latin1(); - TQ_LLONG l = qstrtoll(num_buff, &endptr, base, &_ok); - - if (!_ok || *endptr != '\0') { - if (ok != 0) - *ok = FALSE; - return 0; - } - - if (ok != 0) - *ok = TRUE; - return l; -} - -TQ_ULLONG TQLocalePrivate::stringToUnsLongLong(TQString num, int base, - bool *ok, - GroupSeparatorMode group_sep_mode) const -{ - if (!numberToCLocale(num, group_sep_mode)) { - if (ok != 0) - *ok = FALSE; - return 0; - } - - bool _ok; - const char *endptr; - const char *num_buff = num.latin1(); - TQ_ULLONG l = qstrtoull(num_buff, &endptr, base, &_ok); - - if (!_ok || *endptr != '\0') { - if (ok != 0) - *ok = FALSE; - return 0; - } - - if (ok != 0) - *ok = TRUE; - return l; -} - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; -// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; - -/* - * Convert a string to an TQ_ULLONG integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok) -{ - const char *s = nptr; - TQ_ULLONG acc; - unsigned char c; - TQ_ULLONG qbase, cutoff; - int neg, any, cutlim; - - if (ok != 0) - *ok = TRUE; - - /* - * See strtoq for comments as to the logic used. - */ - s = nptr; - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - if (ok != 0) - *ok = FALSE; - if (endptr != 0) - *endptr = s - 1; - return 0; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - qbase = (unsigned)base; - cutoff = (TQ_ULLONG)ULLONG_MAX / qbase; - cutlim = (TQ_ULLONG)ULLONG_MAX % qbase; - for (acc = 0, any = 0;; c = *s++) { - if (!isascii(c)) - break; - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= qbase; - acc += c; - } - } - if (any < 0) { - acc = ULLONG_MAX; - if (ok != 0) - *ok = FALSE; - } - else if (neg) - acc = (~acc) + 1; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} - - -// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; - - -/* - * Convert a string to a TQ_LLONG integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok) -{ - const char *s; - TQ_ULLONG acc; - unsigned char c; - TQ_ULLONG qbase, cutoff; - int neg, any, cutlim; - - if (ok != 0) - *ok = TRUE; - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for quads is - * [-9223372036854775808..9223372036854775807] and the input base - * is 10, cutoff will be set to 922337203685477580 and cutlim to - * either 7 (neg==0) or 8 (neg==1), meaning that if we have - * accumulated a value > 922337203685477580, or equal but the - * next digit is > 7 (or 8), the number is too big, and we will - * return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - qbase = (unsigned)base; - cutoff = neg ? (TQ_ULLONG)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX - : LLONG_MAX; - cutlim = cutoff % qbase; - cutoff /= qbase; - for (acc = 0, any = 0;; c = *s++) { - if (!isascii(c)) - break; - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= qbase; - acc += c; - } - } - if (any < 0) { - acc = neg ? LLONG_MIN : LLONG_MAX; - if (ok != 0) - *ok = FALSE; - } else if (neg) { - acc = (~acc) + 1; - } - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} - -#ifndef QT_QLOCALE_USES_FCVT - -/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */ -/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */ - -/* Please send bug reports to - David M. Gay - AT&T Bell Laboratories, Room 2C-463 - 600 Mountain Avenue - Murray Hill, NJ 07974-2070 - U.S.A. - dmg@research.att.com or research!dmg - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define Sudden_Underflow for IEEE-format machines without gradual - * underflow (i.e., that flush to zero on underflow). - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic. - * #define Unsigned_Shifts if >> does treats its left operand as unsigned. - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision - * integer arithmetic. Whether this speeds things up or slows things - * down depends on the machine and the number being converted. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $"); -#endif /* LIBC_SCCS and not lint */ - -/* -#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ - defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ - defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MACX) || \ - defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS) -# define IEEE_BIG_OR_LITTLE_ENDIAN 1 -#endif -*/ - -// *All* of our architectures have IEEE arithmetic, don't they? -#define IEEE_BIG_OR_LITTLE_ENDIAN 1 - -#ifdef __arm32__ -/* - * Although the CPU is little endian the FP has different - * byte and word endianness. The byte order is still little endian - * but the word order is big endian. - */ -#define IEEE_BIG_OR_LITTLE_ENDIAN -#endif - -#ifdef vax -#define VAX -#endif - -#define Long TQ_INT32 -#define ULong TQ_UINT32 - -#define MALLOC malloc -#define CONST const - -#ifdef BSD_QDTOA_DEBUG -#include -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#ifdef Unsigned_Shifts -#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; -#else -#define Sign_Extend(a,b) /*no-op*/ -#endif - -#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1 -#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined. -#endif - -inline ULong getWord0(const NEEDS_VOLATILE double x) -{ - const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); - if (ByteOrder == BigEndian) { - return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; - } else { - return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4]; - } -} - -inline void setWord0(NEEDS_VOLATILE double *x, ULong l) -{ - NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); - if (ByteOrder == BigEndian) { - ptr[0] = (uchar)(l>>24); - ptr[1] = (uchar)(l>>16); - ptr[2] = (uchar)(l>>8); - ptr[3] = (uchar)l; - } else { - ptr[7] = (uchar)(l>>24); - ptr[6] = (uchar)(l>>16); - ptr[5] = (uchar)(l>>8); - ptr[4] = (uchar)l; - } -} - -inline ULong getWord1(const NEEDS_VOLATILE double x) -{ - const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); - if (ByteOrder == BigEndian) { - return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7]; - } else { - return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0]; - } -} -inline void setWord1(NEEDS_VOLATILE double *x, ULong l) -{ - NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); - if (ByteOrder == BigEndian) { - ptr[4] = (uchar)(l>>24); - ptr[5] = (uchar)(l>>16); - ptr[6] = (uchar)(l>>8); - ptr[7] = (uchar)l; - } else { - ptr[3] = (uchar)(l>>24); - ptr[2] = (uchar)(l>>16); - ptr[1] = (uchar)(l>>8); - ptr[0] = (uchar)l; - } -} - -static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c) -{ - - *a = (((unsigned short)b) << 16) | ((unsigned short)c); - ++a; -} - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#if defined(IEEE_BIG_OR_LITTLE_ENDIAN) -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define IEEE_Arith -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */ -#else -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Bias 65 -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Bias 129 -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif -#endif - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -extern double rnd_prod(double, double), rnd_quot(double, double); -#else -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Just_16 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#ifndef Pack_32 -#define Pack_32 -#endif -#endif - -#define Kmax 15 - -struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; -}; - - typedef struct Bigint Bigint; - -static Bigint *Balloc(int k) -{ - int x; - Bigint *rv; - - x = 1 << k; - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); - rv->k = k; - rv->maxwds = x; - rv->sign = rv->wds = 0; - return rv; -} - -static void Bfree(Bigint *v) -{ - free(v); -} - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - -/* multiply by m and add a */ -static Bigint *multadd(Bigint *b, int m, int a) -{ - int i, wds; - ULong *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - do { -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + a; - z = (xi >> 16) * m + (y >> 16); - a = (int)(z >> 16); - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + a; - a = (int)(y >> 16); - *x++ = y & 0xffff; -#endif - } - while(++i < wds); - if (a) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = a; - b->wds = wds; - } - return b; -} - -static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9) -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s++; - } - else - s += 10; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; -} - -static int hi0bits(ULong x) -{ - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; -} - -static int lo0bits(ULong *y) -{ - int k; - ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x & 1) - return 32; - } - *y = x; - return k; -} - -static Bigint *i2b(int i) -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; -} - -static Bigint *mult(Bigint *a, Bigint *b) -{ - Bigint *c; - int k, wa, wb, wc; - ULong carry, y, z; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; -#ifdef Pack_32 - ULong z2; -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if ((y = *xb & 0xffff) != 0) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if ((y = *xb >> 16) != 0) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; -} - -static Bigint *p5s; - -static Bigint *pow5mult(Bigint *b, int k) -{ - Bigint *b1, *p5, *p51; - int i; - static const int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3) != 0) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ - p5 = p5s = i2b(625); - p5->next = 0; - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - p5 = p51; - } - return b; -} - -static Bigint *lshift(Bigint *b, int k) -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z) != 0) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; -} - -static int cmp(Bigint *a, Bigint *b) -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef BSD_QDTOA_DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; -} - -static Bigint *diff(Bigint *a, Bigint *b) -{ - Bigint *c; - int i, wa, wb; - Long borrow, y; /* We need signed shifts here. */ - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef Pack_32 - Long z; -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; -} - -static double ulp(double x) -{ - Long L; - double a; - - L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif - setWord0(&a, L); - setWord1(&a, 0); -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - setWord0(&a, 0x80000 >> L); - setWord1(&a, 0); - } - else { - setWord0(&a, 0); - L -= Exp_shift; - setWord1(&a, L >= 31 ? 1U : 1U << (31 - L)); - } - } -#endif - return a; -} - -static double b2d(Bigint *a, int *e) -{ - ULong *xa, *xa0, w, y, z; - int k; - double d; - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef BSD_QDTOA_DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - setWord0(&d, Exp_1 | y >> (Ebits - k)); - w = xa > xa0 ? *--xa : 0; - setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k)); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - setWord0(&d, Exp_1 | y << k | z >> (32 - k)); - y = xa > xa0 ? *--xa : 0; - setWord1(&d, z << k | y >> (32 - k)); - } - else { - setWord0(&d, Exp_1 | y); - setWord1(&d, z); - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k); - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k); - y = xa > xa0 ? *--xa : 0; - setWord1(&d, w << k + 16 | y << k); -#endif - ret_d: - return d; -} - -static Bigint *d2b(double d, int *e, int *bits) -{ - Bigint *b; - int de, i, k; - ULong *x, y, z; - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = getWord0(d) & Frac_mask; - setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(getWord0(d) >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - if ((de = (int)(getWord0(d) >> Exp_shift)) != 0) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if ((y = getWord1(d)) != 0) { - if ((k = lo0bits(&y)) != 0) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; - i = b->wds = (x[1] = z) ? 2 : 1; - } - else { -#ifdef BSD_QDTOA_DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - x[0] = z; - i = b->wds = 1; - k += 32; - } -#else - if (y = getWord1(d)) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef BSD_QDTOA_DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; -} - -static double ratio(Bigint *a, Bigint *b) -{ - double da, db; - int k, ka, kb; - - da = b2d(a, &ka); - db = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1); - if (k &= 3) - da *= 1 << k; - } - else { - k = -k; - setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1); - if (k &= 3) - db *= 1 << k; - } -#else - if (k > 0) - setWord0(&da, getWord0(da) + k*Exp_msk1); - else { - k = -k; - setWord0(&db, getWord0(db) + k*Exp_msk1); - } -#endif - return da / db; -} - -static CONST double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif -}; - -#ifdef IEEE_Arith -static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; -#define n_bigtens 5 -#else -#ifdef IBM -static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -static CONST double bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - -/* - The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes - the comparison 1e-100 == 0.0 to return true. As a workaround, we - compare it to a global variable containing 0.0, which produces - correct assembler output. - - ### consider detecting the broken compilers and using the static - ### double for these, and use a #define for all working compilers -*/ -static double g_double_zero = 0.0; - -static double qstrtod(CONST char *s00, CONST char **se, bool *ok) -{ - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1, adj, rv, rv0; - Long L; - ULong y, z; - Bigint *bb1, *bd0; - Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */ - - /* - #ifndef KR_headers - CONST char decimal_point = localeconv()->decimal_point[0]; - #else - CONST char decimal_point = '.'; - #endif */ - if (ok != 0) - *ok = TRUE; - - CONST char decimal_point = '.'; - - sign = nz0 = nz = 0; - rv = 0.; - - - for(s = s00; isspace((unsigned char) *s); s++) - ; - - if (*s == '-') { - sign = 1; - s++; - } else if (*s == '+') { - s++; - } - - if (*s == '\0') { - s = s00; - goto ret; - } - - if (*s == '0') { - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; - if (c == decimal_point) { - c = *++s; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - s = s00; - goto ret; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) - s = s00; - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - rv = y; - if (k > 9) - rv = tens[k - 9] * rv + z; - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT - && FLT_ROUNDS == 1 -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else - /* rv = */ rounded_product(rv, tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ - e -= i; - rv *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - /* rv = */ rounded_product(rv, tens[e]); - if ((getWord0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - setWord0(&rv, getWord0(rv) + P*Exp_msk1); -#else - /* rv = */ rounded_product(rv, tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(rv, tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15) != 0) - rv *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: - // errno = ERANGE; - if (ok != 0) - *ok = FALSE; -#ifdef __STDC__ - rv = HUGE_VAL; -#else - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith - setWord0(&rv, Exp_mask); - setWord1(&rv, 0); -#else - setWord0(&rv, Big0); - setWord1(&rv, Big1); -#endif -#endif - if (bd0) - goto retfree; - goto ret; - } - if (e1 >>= 4) { - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - rv *= bigtens[j]; - /* The last multiplication could overflow. */ - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - rv *= bigtens[j]; - if ((z = getWord0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - setWord0(&rv, Big0); - setWord1(&rv, Big1); - } - else - setWord0(&rv, getWord0(rv) + P*Exp_msk1); - } - - } - } - else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15) != 0) - rv /= tens[i]; - if (e1 &= ~15) { - e1 >>= 4; - if (e1 >= 1 << n_bigtens) - goto undfl; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - rv *= tinytens[j]; - /* The last multiplication could underflow. */ - rv0 = rv; - rv *= tinytens[j]; - if (rv == g_double_zero) - { - rv = 2.*rv0; - rv *= tinytens[j]; - if (rv == g_double_zero) - { - undfl: - rv = 0.; - // errno = ERANGE; - if (ok != 0) - *ok = FALSE; - if (bd0) - goto retfree; - goto ret; - } - setWord0(&rv, Tiny0); - setWord1(&rv, Tiny1); - /* The refinement below will clean - * this approximation up. - */ - } - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else - i = bbe + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j = bbe + (P-Emin); - else - j = P + 1 - bbbits; -#endif - bb2 += j; - bd2 += j; - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) - break; - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1 - && getWord1(rv) == 0xffffffff) { - /*boundary case -- increment exponent*/ - setWord0(&rv, (getWord0(rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ); - setWord1(&rv, 0); - break; - } - } - else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) { - drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow - L = getWord0(rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else - if (L <= Exp_msk1) -#endif - goto undfl; - L -= Exp_msk1; -#else - L = (getWord0(rv) & Exp_mask) - Exp_msk1; -#endif - setWord0(&rv, L | Bndry_mask1); - setWord1(&rv, 0xffffffff); -#ifdef IBM - goto cont; -#else - break; -#endif - } -#ifndef ROUND_BIASED - if (!(getWord1(rv) & LSB)) - break; -#endif - if (dsign) - rv += ulp(rv); -#ifndef ROUND_BIASED - else { - rv -= ulp(rv); -#ifndef Sudden_Underflow - if (rv == g_double_zero) - goto undfl; -#endif - } -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (getWord1(rv) || getWord0(rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (getWord1(rv) == Tiny1 && !getWord0(rv)) - goto undfl; -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(FLT_ROUNDS) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (FLT_ROUNDS == 0) - aadj1 += 0.5; -#endif - } - y = getWord0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - rv0 = rv; - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - adj = aadj1 * ulp(rv); - rv += adj; - if ((getWord0(rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1) - goto ovfl; - setWord0(&rv, Big0); - setWord1(&rv, Big1); - goto cont; - } - else - setWord0(&rv, getWord0(rv) + P*Exp_msk1); - } - else { -#ifdef Sudden_Underflow - if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) { - rv0 = rv; - setWord0(&rv, getWord0(rv) + P*Exp_msk1); - adj = aadj1 * ulp(rv); - rv += adj; -#ifdef IBM - if ((getWord0(rv) & Exp_mask) < P*Exp_msk1) -#else - if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (getWord0(rv0) == Tiny0 - && getWord1(rv0) == Tiny1) - goto undfl; - setWord0(&rv, Tiny0); - setWord1(&rv, Tiny1); - goto cont; - } - else - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - } - else { - adj = aadj1 * ulp(rv); - rv += adj; - } -#else - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!dsign) - aadj1 = -aadj1; - } - adj = aadj1 * ulp(rv); - rv += adj; -#endif - } - z = getWord0(rv) & Exp_mask; - if (y == z) { - /* Can we stop now? */ - L = (Long) aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - ret: - if (se) - *se = (char *)s; - return sign ? -rv : rv; -} - -static int quorem(Bigint *b, Bigint *S) -{ - int n; - Long borrow, y; - ULong carry, q, ys; - ULong *bx, *bxe, *sx, *sxe; -#ifdef Pack_32 - Long z; - ULong si, zs; -#endif - - n = S->wds; -#ifdef BSD_QDTOA_DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef BSD_QDTOA_DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; -} - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - -/* This actually sometimes returns a pointer to a string literal - cast to a char*. Do NOT try to modify the return value. */ - -static char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) -{ - // Some values of the floating-point control word can cause _qdtoa to crash with an underflow. - // We set a safe value here. -#ifdef Q_OS_WIN -#ifndef Q_CC_BOR - unsigned int oldbits = _control87(0, 0); -#ifndef _M_X64 //x64 does not support precition control - _control87(0x9001F, 0xFFFFF); -#else - _control87(0x9001F, _MCW_DN|_MCW_EM|_MCW_RC); -#endif //_M_X64 -#endif -#endif - -#ifdef Q_OS_LINUX - fenv_t envp; - feholdexcept(&envp); -#endif - - char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp); - -#ifdef Q_OS_WIN -#ifndef Q_CC_BOR - _clear87(); -#ifndef _M_X64 - _control87(oldbits, 0xFFFFF); -#else - _control87(oldbits, _MCW_DN|_MCW_EM|_MCW_RC); -#endif //_M_X64 -#endif -#endif - -#ifdef Q_OS_LINUX - fesetenv(&envp); -#endif - - return s; -} - -static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) -{ - /* - Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4-9 should give the same return values as 2-3, i.e., - 4 <= mode <= 9 ==> same return as mode - 2 + (mode & 1). These modes are mainly for - debugging; often they run slower but sometimes - faster than modes 2-3. - 4,5,8,9 ==> left-to-right digit generation. - 6-9 ==> don't try fast floating-point estimate - (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim0, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - try_quick; - int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */ - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mhi, *S; - Bigint *mlo = NULL; /* pacify gcc */ - double d2; - double ds, eps; - char *s, *s0; - - if (getWord0(d) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((getWord0(d) & Exp_mask) == Exp_mask) -#else - if (getWord0(d) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; - s = -#ifdef IEEE_Arith - !getWord1(d) && !(getWord0(d) & 0xfffff) ? (char*)"Infinity" : -#endif - (char*)"NaN"; - if (rve) - *rve = -#ifdef IEEE_Arith - s[3] ? s + 8 : -#endif - s + 3; - return s; - } -#endif -#ifdef IBM - d += 0; /* normalize */ -#endif - if (d == g_double_zero) - { - *decpt = 1; - s = (char*) "0"; - if (rve) - *rve = s + 1; - return s; - } - - b = d2b(d, &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else - if ((i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { -#endif - d2 = d; - setWord0(&d2, getWord0(d2) & Frac_mask1); - setWord0(&d2, getWord0(d2) | Exp_11); -#ifdef IBM - if (j = 11 - hi0bits(getWord0(d2) & Frac_mask)) - d2 /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32) - : getWord1(d) << (32 - i); - d2 = x; - setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (d < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - try_quick = 1; - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - switch(mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - *resultp = (char *) malloc(i + 1); - s = s0 = *resultp; - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - d2 = d; - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - d /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - d /= ds; - } - else if ((j1 = -k) != 0) { - d *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - d *= bigtens[i]; - } - } - if (k_check && d < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - d *= 10.; - ieps++; - } - eps = ieps*d + 7.; - setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1); - if (ilim == 0) { - S = mhi = 0; - d -= 5.; - if (d > eps) - goto one_digit; - if (d < -eps) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - eps = 0.5/tens[ilim-1] - eps; - for(i = 0;;) { - L = (Long)d; - d -= L; - *s++ = '0' + (int)L; - if (d < eps) - goto ret1; - if (1. - d < eps) - goto bump_up; - if (++i >= ilim) - break; - eps *= 10.; - d *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - eps *= tens[ilim-1]; - for(i = 1;; i++, d *= 10.) { - L = (Long)d; - d -= L; - *s++ = '0' + (int)L; - if (i == ilim) { - if (d > 0.5 + eps) - goto bump_up; - else if (d < 0.5 - eps) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - d = d2; - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || d <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++) { - L = (Long)(d / ds); - d -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (d < 0) { - L--; - d += ds; - } -#endif - *s++ = '0' + (int)L; - if (i == ilim) { - d += d; - if (d > ds || (d == ds && L & 1)) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - if ((d *= 10.) == g_double_zero) - break; - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - if (mode < 2) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - } - else { - j = ilim - 1; - if (m5 >= j) - m5 -= j; - else { - s5 += j -= m5; - b5 += j; - m5 = 0; - } - if ((i = ilim) < 0) { - m2 -= i; - i = 0; - } - } - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if ((j = b5 - m5) != 0) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - if (mode < 2) { - if (!getWord1(d) && !(getWord0(d) & Bndry_mask) -#ifndef Sudden_Underflow - && getWord0(d) & Exp_mask -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - else - spec_case = 0; - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#ifdef Pack_32 - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) - i = 32 - i; -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && mode > 2) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && !mode && !(getWord1(d) & 1)) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || (j == 0 && !mode -#ifndef ROUND_BIASED - && !(getWord1(d) & 1) -#endif - )) { - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && dig & 1)) - && dig++ == '9') - goto round_9_up; - } - *s++ = dig; - goto ret; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } - - /* Round off last digit */ - - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || (j == 0 && dig & 1)) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: - Bfree(b); - if (s == s0) { /* don't return empty string */ - *s++ = '0'; - k = 0; - } - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; -} - -#endif // QT_QLOCALE_USES_FCVT diff --git a/src/tools/qlocale_p.h b/src/tools/qlocale_p.h deleted file mode 100644 index 8d562d22c..000000000 --- a/src/tools/qlocale_p.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Declaration of the TQLocalePrivate class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQLOCALE_P_H -#define TQLOCALE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the TQt API. It exists for the convenience -// of internal files. This header file may change from version to version -// without notice, or even be removed. -// -// We mean it. -// -// - -#include - -struct TQLocalePrivate -{ -public: - const TQChar &decimal() const { return (TQChar&)m_decimal; } - const TQChar &group() const { return (TQChar&)m_group; } - const TQChar &list() const { return (TQChar&)m_list; } - const TQChar &percent() const { return (TQChar&)m_percent; } - const TQChar &zero() const { return (TQChar&)m_zero; } - TQChar plus() const { return TQChar('+'); } - const TQChar &minus() const { return (TQChar&)m_minus; } - const TQChar &exponential() const { return (TQChar&)m_exponential; } - TQString infinity() const; - TQString nan() const; - - TQ_UINT32 languageId() const { return m_language_id; } - TQ_UINT32 countryId() const { return m_country_id; } - - bool isDigit(TQChar d) const; - - enum GroupSeparatorMode { - FailOnGroupSeparators, - ParseGroupSeparators - }; - - enum DoubleForm { - DFExponent = 0, // %e or %E - DFDecimal, // %f or %F - DFSignificantDigits, // %g or %G - _DFMax = DFSignificantDigits - }; - - enum Flags { - NoFlags = 0, - - // These correspond to the options in a printf format string - Alternate = 0x01, - ZeroPadded = 0x02, - LeftAdjusted = 0x04, - BlankBeforePositive = 0x08, - AlwaysShowSign = 0x10, - ThousandsGroup = 0x20, - CapitalEorX = 0x40 // %x, %e, %f, %g vs. %X, %E, %F, %G - }; - - TQString doubleToString(double d, - int precision = -1, - DoubleForm form = DFSignificantDigits, - int width = -1, - unsigned flags = NoFlags) const; - TQString longLongToString(TQ_LLONG l, int precision = -1, - int base = 10, - int width = -1, - unsigned flags = NoFlags) const; - TQString unsLongLongToString(TQ_ULLONG l, int precision = -1, - int base = 10, - int width = -1, - unsigned flags = NoFlags) const; - double stringToDouble(TQString num, bool *ok, GroupSeparatorMode group_sep_mode) const; - TQ_LLONG stringToLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; - TQ_ULLONG stringToUnsLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; - bool removeGroupSeparators(TQString &num_str) const; - bool numberToCLocale(TQString &locale_num, GroupSeparatorMode group_sep_mode) const; - - TQ_UINT32 m_language_id, m_country_id; - - TQ_UINT16 m_decimal, m_group, m_list, m_percent, - m_zero, m_minus, m_exponential; - - static const TQString m_infinity; - static const TQString m_nan; - static const TQChar m_plus; - - static const char *systemLocaleName(); -}; - -#endif diff --git a/src/tools/qt_tools.pri b/src/tools/qt_tools.pri index c4cced519..5eb816580 100644 --- a/src/tools/qt_tools.pri +++ b/src/tools/qt_tools.pri @@ -34,8 +34,8 @@ tools { $$TOOLS_H/tqiodevice.h \ $$TOOLS_H/ntqlibrary.h \ $$TOOLS_P/qlibrary_p.h \ - $$TOOLS_H/ntqlocale.h \ - $$TOOLS_P/qlocale_p.h \ + $$TOOLS_H/tqlocale.h \ + $$TOOLS_P/tqlocale_p.h \ $$TOOLS_H/tqptrlist.h \ $$TOOLS_H/tqmap.h \ $$TOOLS_H/tqmutex.h \ @@ -126,7 +126,7 @@ tools { $$TOOLS_CPP/qgvector.cpp \ $$TOOLS_CPP/tqiodevice.cpp \ $$TOOLS_CPP/qlibrary.cpp \ - $$TOOLS_CPP/qlocale.cpp \ + $$TOOLS_CPP/tqlocale.cpp \ $$TOOLS_CPP/tqmap.cpp \ $$TOOLS_CPP/tqmutexpool.cpp \ $$TOOLS_CPP/tqptrcollection.cpp \ @@ -143,7 +143,7 @@ tools { irix-cc* { CXXFLAGS_PRELINK = $$QMAKE_CXXFLAGS CXXFLAGS_PRELINK -= -O2 - QMAKE_PRE_LINK = $(CXX) -c $$CXXFLAGS_PRELINK -O1 $(INCPATH) -o $(OBJECTS_DIR)/qlocale.o tools/qlocale.cpp + QMAKE_PRE_LINK = $(CXX) -c $$CXXFLAGS_PRELINK -O1 $(INCPATH) -o $(OBJECTS_DIR)/tqlocale.o tools/tqlocale.cpp } } diff --git a/src/tools/tqlocale.cpp b/src/tools/tqlocale.cpp new file mode 100644 index 000000000..57ddcfb3f --- /dev/null +++ b/src/tools/tqlocale.cpp @@ -0,0 +1,6322 @@ +/**************************************************************************** +** +** Implementation of the TQLocale class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the tools module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "tqlocale.h" +#include "tqlocale_p.h" +#include "ntqnamespace.h" + +#ifdef QT_QLOCALE_USES_FCVT +# include +# include +#endif + +#if defined (Q_OS_WIN) +# include +# undef NAN // we want to use our fallback on Windows +# undef INFINITY +#endif + +#ifdef Q_OS_LINUX +# include +#endif + +#if defined( Q_OS_MAC ) +# include +#endif + +#if defined (Q_OS_SOLARIS) +# include +#endif + +#if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) +# define INFINITY DBL_INFINITY +# define NAN DBL_QNAN +#endif + +#if (defined(Q_CC_GNU) && defined(Q_OS_WIN)) || __GNUC__ == 4 || defined(QT_QLOCALE_NEEDS_VOLATILE) +# define NEEDS_VOLATILE volatile +#else +# define NEEDS_VOLATILE +#endif + +enum { + LittleEndian, + BigEndian + +#ifdef TQ_BYTE_ORDER +# if TQ_BYTE_ORDER == TQ_BIG_ENDIAN + , ByteOrder = BigEndian +# elif TQ_BYTE_ORDER == TQ_LITTLE_ENDIAN + , ByteOrder = LittleEndian +# else +# error "undefined byte order" +# endif +}; +#else +}; +static const unsigned int one = 1; +static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); +#endif + +#if !defined(INFINITY) +static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +static inline double inf() +{ + return (ByteOrder == BigEndian ? + *((const double *) be_inf_bytes) : + *((const double *) le_inf_bytes)); +} +# define INFINITY (::inf()) +#endif + +#if !defined(NAN) +static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; +static inline double nan() +{ + return (ByteOrder == BigEndian ? + *((const double *) be_nan_bytes) : + *((const double *) le_nan_bytes)); +} +# define NAN (::nan()) +#endif + +// We can't rely on -NAN, since all operations on a NAN should return a NAN. +static double be_neg_nan; +static double le_neg_nan; +static const unsigned char be_neg_nan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_neg_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff }; +static bool neg_nan_init = false; + +static inline double negNan() +{ + if (!neg_nan_init) + { + memcpy(&be_neg_nan,be_neg_nan_bytes,sizeof(be_neg_nan_bytes)); + memcpy(&le_neg_nan,le_neg_nan_bytes,sizeof(le_neg_nan_bytes)); + neg_nan_init = true; + } + return (ByteOrder == BigEndian ? + be_neg_nan : + le_neg_nan); + +} + +// Sizes as defined by the ISO C99 standard - fallback +#ifndef LLONG_MAX +# define LLONG_MAX TQ_INT64_C(9223372036854775807) +#endif +#ifndef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - TQ_INT64_C(1)) +#endif +#ifndef ULLONG_MAX +# define ULLONG_MAX TQ_UINT64_C(0xffffffffffffffff) +#endif + +#ifndef QT_QLOCALE_USES_FCVT +static char *qdtoa(double d, int mode, int ndigits, int *decpt, + int *sign, char **rve, char **digits_str); +static char *_qdtoa(double d, int mode, int ndigits, int *decpt, + int *sign, char **rve, char **digits_str); +static double qstrtod(const char *s00, char const **se, bool *ok); +#endif +static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok); +static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok); + +static inline bool compareBits(double d1, double d2) +{ + return memcmp((const char*)&d1, (const char*)&d2, sizeof(double)) == 0; +} + +static inline bool qIsInf(double d) +{ + return compareBits(d, INFINITY) || compareBits(d, -INFINITY); +} + +static inline bool qIsNan(double d) +{ + return compareBits(d, NAN) || compareBits(d, negNan()); +} + +static const uint locale_index[] = { + 0, // unused + 0, // C + 0, // Abkhazian + 0, // Afan + 0, // Afar + 1, // Afrikaans + 2, // Albanian + 0, // Amharic + 3, // Arabic + 19, // Armenian + 0, // Assamese + 0, // Aymara + 20, // Azerbaijani + 0, // Bashkir + 21, // Basque + 22, // Bengali + 0, // Bhutani + 0, // Bihari + 0, // Bislama + 0, // Breton + 23, // Bulgarian + 0, // Burmese + 24, // Byelorussian + 0, // Cambodian + 25, // Catalan + 26, // Chinese + 0, // Corsican + 31, // Croatian + 32, // Czech + 33, // Danish + 34, // Dutch + 36, // English + 0, // Esperanto + 48, // Estonian + 49, // Faroese + 0, // Fiji + 50, // Finnish + 51, // French + 0, // Frisian + 0, // Gaelic + 57, // Galician + 58, // Georgian + 59, // German + 64, // Greek + 0, // Greenlandic + 0, // Guarani + 65, // Gujarati + 0, // Hausa + 66, // Hebrew + 67, // Hindi + 68, // Hungarian + 69, // Icelandic + 70, // Indonesian + 0, // Interlingua + 0, // Interlingue + 0, // Inuktitut + 0, // Inupiak + 0, // Irish + 71, // Italian + 73, // Japanese + 0, // Javanese + 74, // Kannada + 0, // Kashmiri + 75, // Kazakh + 0, // Kinyarwanda + 76, // Kirghiz + 77, // Korean + 0, // Kurdish + 0, // Kurundi + 0, // Laothian + 0, // Latin + 78, // Latvian + 0, // Lingala + 79, // Lithuanian + 80, // Macedonian + 0, // Malagasy + 81, // Malay + 0, // Malayalam + 0, // Maltese + 0, // Maori + 83, // Marathi + 0, // Moldavian + 84, // Mongolian + 0, // Nauru + 0, // Nepali + 85, // Norwegian + 0, // Occitan + 0, // Oriya + 0, // Pashto + 86, // Persian + 87, // Polish + 88, // Portuguese + 90, // Punjabi + 0, // Quechua + 0, // RhaetoRomance + 91, // Romanian + 92, // Russian + 0, // Samoan + 0, // Sangho + 93, // Sanskrit + 0, // Serbian + 0, // SerboCroatian + 0, // Sesotho + 0, // Setswana + 0, // Shona + 0, // Sindhi + 0, // Singhalese + 0, // Siswati + 94, // Slovak + 95, // Slovenian + 0, // Somali + 96, // Spanish + 0, // Sundanese + 115, // Swahili + 116, // Swedish + 0, // Tagalog + 0, // Tajik + 118, // Tamil + 0, // Tatar + 119, // Telugu + 120, // Thai + 0, // Tibetan + 0, // Tigrinya + 0, // Tonga + 0, // Tsonga + 121, // Turkish + 0, // Turkmen + 0, // Twi + 0, // Uigur + 122, // Ukrainian + 123, // Urdu + 124, // Uzbek + 125, // Vietnamese + 0, // Volapuk + 0, // Welsh + 0, // Wolof + 0, // Xhosa + 0, // Yiddish + 0, // Yoruba + 0, // Zhuang + 0, // Zulu + 0 // trailing 0 +}; + +static const TQLocalePrivate locale_data[] = { +// lang terr dec group list prcnt zero minus exp + { 1, 0, 46, 44, 59, 37, 48, 45, 101 }, // C/AnyCountry + { 5, 195, 46, 44, 44, 37, 48, 45, 101 }, // Afrikaans/SouthAfrica + { 6, 2, 44, 46, 59, 37, 48, 45, 101 }, // Albanian/Albania + { 8, 186, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SaudiArabia + { 8, 3, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Algeria + { 8, 17, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Bahrain + { 8, 64, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Egypt + { 8, 103, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Iraq + { 8, 109, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Jordan + { 8, 115, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Kuwait + { 8, 119, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Lebanon + { 8, 122, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/LibyanArabJamahiriya + { 8, 145, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Morocco + { 8, 162, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Oman + { 8, 175, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Qatar + { 8, 207, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SyrianArabRepublic + { 8, 216, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Tunisia + { 8, 223, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/UnitedArabEmirates + { 8, 237, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Yemen + { 9, 11, 46, 44, 44, 37, 48, 45, 101 }, // Armenian/Armenia + { 12, 15, 44, 160, 59, 37, 48, 45, 101 }, // Azerbaijani/Azerbaijan + { 14, 197, 44, 46, 59, 37, 48, 45, 101 }, // Basque/Spain + { 15, 100, 46, 44, 59, 37, 48, 45, 101 }, // Bengali/India + { 20, 33, 44, 160, 59, 37, 48, 45, 101 }, // Bulgarian/Bulgaria + { 22, 20, 44, 160, 59, 37, 48, 45, 101 }, // Byelorussian/Belarus + { 24, 197, 44, 46, 59, 37, 48, 45, 101 }, // Catalan/Spain + { 25, 44, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/China + { 25, 97, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/HongKong + { 25, 126, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Macau + { 25, 190, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Singapore + { 25, 208, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Taiwan + { 27, 54, 44, 46, 59, 37, 48, 45, 101 }, // Croatian/Croatia + { 28, 57, 44, 160, 59, 37, 48, 45, 101 }, // Czech/CzechRepublic + { 29, 58, 44, 46, 59, 37, 48, 45, 101 }, // Danish/Denmark + { 30, 151, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Netherlands + { 30, 21, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Belgium + { 31, 225, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedStates + { 31, 13, 46, 44, 44, 37, 48, 45, 101 }, // English/Australia + { 31, 22, 46, 44, 59, 37, 48, 45, 101 }, // English/Belize + { 31, 38, 46, 44, 44, 37, 48, 45, 101 }, // English/Canada + { 31, 104, 46, 44, 44, 37, 48, 45, 101 }, // English/Ireland + { 31, 107, 46, 44, 44, 37, 48, 45, 101 }, // English/Jamaica + { 31, 154, 46, 44, 44, 37, 48, 45, 101 }, // English/NewZealand + { 31, 170, 46, 44, 44, 37, 48, 45, 101 }, // English/Philippines + { 31, 195, 46, 44, 44, 37, 48, 45, 101 }, // English/SouthAfrica + { 31, 215, 46, 44, 59, 37, 48, 45, 101 }, // English/TrinidadAndTobago + { 31, 224, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedKingdom + { 31, 240, 46, 44, 44, 37, 48, 45, 101 }, // English/Zimbabwe + { 33, 68, 44, 160, 59, 37, 48, 45, 101 }, // Estonian/Estonia + { 34, 71, 44, 46, 59, 37, 48, 45, 101 }, // Faroese/FaroeIslands + { 36, 73, 44, 160, 59, 37, 48, 45, 101 }, // Finnish/Finland + { 37, 74, 44, 160, 59, 37, 48, 45, 101 }, // French/France + { 37, 21, 44, 46, 59, 37, 48, 45, 101 }, // French/Belgium + { 37, 38, 44, 160, 59, 37, 48, 45, 101 }, // French/Canada + { 37, 125, 44, 160, 59, 37, 48, 45, 101 }, // French/Luxembourg + { 37, 142, 44, 160, 59, 37, 48, 45, 101 }, // French/Monaco + { 37, 206, 46, 39, 59, 37, 48, 45, 101 }, // French/Switzerland + { 40, 197, 44, 46, 44, 37, 48, 45, 101 }, // Galician/Spain + { 41, 81, 44, 160, 59, 37, 48, 45, 101 }, // Georgian/Georgia + { 42, 82, 44, 46, 59, 37, 48, 45, 101 }, // German/Germany + { 42, 14, 44, 46, 59, 37, 48, 45, 101 }, // German/Austria + { 42, 123, 46, 39, 59, 37, 48, 45, 101 }, // German/Liechtenstein + { 42, 125, 44, 46, 59, 37, 48, 45, 101 }, // German/Luxembourg + { 42, 206, 46, 39, 59, 37, 48, 45, 101 }, // German/Switzerland + { 43, 85, 44, 46, 59, 37, 48, 45, 101 }, // Greek/Greece + { 46, 100, 46, 44, 44, 37, 2790, 45, 101 }, // Gujarati/India + { 48, 105, 46, 44, 44, 37, 48, 45, 101 }, // Hebrew/Israel + { 49, 100, 46, 44, 44, 37, 48, 45, 101 }, // Hindi/India + { 50, 98, 44, 160, 59, 37, 48, 45, 101 }, // Hungarian/Hungary + { 51, 99, 44, 46, 59, 37, 48, 45, 101 }, // Icelandic/Iceland + { 52, 101, 44, 46, 59, 37, 48, 45, 101 }, // Indonesian/Indonesia + { 58, 106, 44, 46, 59, 37, 48, 45, 101 }, // Italian/Italy + { 58, 206, 46, 39, 59, 37, 48, 45, 101 }, // Italian/Switzerland + { 59, 108, 46, 44, 44, 37, 48, 45, 101 }, // Japanese/Japan + { 61, 100, 46, 44, 44, 37, 3302, 45, 101 }, // Kannada/India + { 63, 110, 44, 160, 59, 37, 48, 45, 101 }, // Kazakh/Kazakhstan + { 65, 116, 44, 160, 59, 37, 48, 45, 101 }, // Kirghiz/Kyrgyzstan + { 66, 114, 46, 44, 44, 37, 48, 45, 101 }, // Korean/RepublicOfKorea + { 71, 118, 44, 160, 59, 37, 48, 45, 101 }, // Latvian/Latvia + { 73, 124, 44, 46, 59, 37, 48, 45, 101 }, // Lithuanian/Lithuania + { 74, 127, 44, 46, 59, 37, 48, 45, 101 }, // Macedonian/Macedonia + { 76, 130, 44, 46, 59, 37, 48, 45, 101 }, // Malay/Malaysia + { 76, 32, 44, 46, 59, 37, 48, 45, 101 }, // Malay/BruneiDarussalam + { 80, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Marathi/India + { 82, 143, 44, 160, 59, 37, 48, 45, 101 }, // Mongolian/Mongolia + { 85, 161, 44, 160, 59, 37, 48, 45, 101 }, // Norwegian/Norway + { 89, 102, 46, 44, 59, 37, 1776, 45, 101 }, // Persian/Iran + { 90, 172, 44, 160, 59, 37, 48, 45, 101 }, // Polish/Poland + { 91, 173, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Portugal + { 91, 30, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Brazil + { 92, 100, 46, 44, 44, 37, 2662, 45, 101 }, // Punjabi/India + { 95, 177, 44, 46, 59, 37, 48, 45, 101 }, // Romanian/Romania + { 96, 178, 44, 160, 59, 37, 48, 45, 101 }, // Russian/RussianFederation + { 99, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Sanskrit/India + { 108, 191, 44, 160, 59, 37, 48, 45, 101 }, // Slovak/Slovakia + { 109, 192, 44, 46, 59, 37, 48, 45, 101 }, // Slovenian/Slovenia + { 111, 197, 44, 46, 59, 37, 48, 45, 101 }, // Spanish/Spain + { 111, 10, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Argentina + { 111, 26, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Bolivia + { 111, 43, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Chile + { 111, 47, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Colombia + { 111, 52, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/CostaRica + { 111, 61, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/DominicanRepublic + { 111, 63, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Ecuador + { 111, 65, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/ElSalvador + { 111, 90, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Guatemala + { 111, 96, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Honduras + { 111, 139, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Mexico + { 111, 155, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Nicaragua + { 111, 166, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Panama + { 111, 168, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Paraguay + { 111, 169, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Peru + { 111, 174, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/PuertoRico + { 111, 227, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Uruguay + { 111, 231, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Venezuela + { 113, 111, 46, 44, 44, 37, 48, 45, 101 }, // Swahili/Kenya + { 114, 205, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Sweden + { 114, 73, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Finland + { 117, 100, 46, 44, 44, 37, 48, 45, 101 }, // Tamil/India + { 119, 100, 46, 44, 44, 37, 3174, 45, 101 }, // Telugu/India + { 120, 211, 46, 44, 44, 37, 3664, 45, 101 }, // Thai/Thailand + { 125, 217, 44, 46, 59, 37, 48, 45, 101 }, // Turkish/Turkey + { 129, 222, 44, 160, 59, 37, 48, 45, 101 }, // Ukrainian/Ukraine + { 130, 163, 46, 44, 59, 37, 1776, 45, 101 }, // Urdu/Pakistan + { 131, 228, 44, 160, 59, 37, 48, 45, 101 }, // Uzbek/Uzbekistan + { 132, 232, 44, 46, 44, 37, 48, 45, 101 }, // Vietnamese/VietNam + { 0, 0, 0, 0, 0, 0, 0, 0, 0 } // trailing 0s +}; + +static const char language_name_list[] = +"Default\0" +"C\0" +"Abkhazian\0" +"Afan\0" +"Afar\0" +"Afrikaans\0" +"Albanian\0" +"Amharic\0" +"Arabic\0" +"Armenian\0" +"Assamese\0" +"Aymara\0" +"Azerbaijani\0" +"Bashkir\0" +"Basque\0" +"Bengali\0" +"Bhutani\0" +"Bihari\0" +"Bislama\0" +"Breton\0" +"Bulgarian\0" +"Burmese\0" +"Byelorussian\0" +"Cambodian\0" +"Catalan\0" +"Chinese\0" +"Corsican\0" +"Croatian\0" +"Czech\0" +"Danish\0" +"Dutch\0" +"English\0" +"Esperanto\0" +"Estonian\0" +"Faroese\0" +"Fiji\0" +"Finnish\0" +"French\0" +"Frisian\0" +"Gaelic\0" +"Galician\0" +"Georgian\0" +"German\0" +"Greek\0" +"Greenlandic\0" +"Guarani\0" +"Gujarati\0" +"Hausa\0" +"Hebrew\0" +"Hindi\0" +"Hungarian\0" +"Icelandic\0" +"Indonesian\0" +"Interlingua\0" +"Interlingue\0" +"Inuktitut\0" +"Inupiak\0" +"Irish\0" +"Italian\0" +"Japanese\0" +"Javanese\0" +"Kannada\0" +"Kashmiri\0" +"Kazakh\0" +"Kinyarwanda\0" +"Kirghiz\0" +"Korean\0" +"Kurdish\0" +"Kurundi\0" +"Laothian\0" +"Latin\0" +"Latvian\0" +"Lingala\0" +"Lithuanian\0" +"Macedonian\0" +"Malagasy\0" +"Malay\0" +"Malayalam\0" +"Maltese\0" +"Maori\0" +"Marathi\0" +"Moldavian\0" +"Mongolian\0" +"Nauru\0" +"Nepali\0" +"Norwegian\0" +"Occitan\0" +"Oriya\0" +"Pashto\0" +"Persian\0" +"Polish\0" +"Portuguese\0" +"Punjabi\0" +"Quechua\0" +"RhaetoRomance\0" +"Romanian\0" +"Russian\0" +"Samoan\0" +"Sangho\0" +"Sanskrit\0" +"Serbian\0" +"SerboCroatian\0" +"Sesotho\0" +"Setswana\0" +"Shona\0" +"Sindhi\0" +"Singhalese\0" +"Siswati\0" +"Slovak\0" +"Slovenian\0" +"Somali\0" +"Spanish\0" +"Sundanese\0" +"Swahili\0" +"Swedish\0" +"Tagalog\0" +"Tajik\0" +"Tamil\0" +"Tatar\0" +"Telugu\0" +"Thai\0" +"Tibetan\0" +"Tigrinya\0" +"Tonga\0" +"Tsonga\0" +"Turkish\0" +"Turkmen\0" +"Twi\0" +"Uigur\0" +"Ukrainian\0" +"Urdu\0" +"Uzbek\0" +"Vietnamese\0" +"Volapuk\0" +"Welsh\0" +"Wolof\0" +"Xhosa\0" +"Yiddish\0" +"Yoruba\0" +"Zhuang\0" +"Zulu\0"; + +static const uint language_name_index[] = { + 0,// Unused + 8,// C + 10,// Abkhazian + 20,// Afan + 25,// Afar + 30,// Afrikaans + 40,// Albanian + 49,// Amharic + 57,// Arabic + 64,// Armenian + 73,// Assamese + 82,// Aymara + 89,// Azerbaijani + 101,// Bashkir + 109,// Basque + 116,// Bengali + 124,// Bhutani + 132,// Bihari + 139,// Bislama + 147,// Breton + 154,// Bulgarian + 164,// Burmese + 172,// Byelorussian + 185,// Cambodian + 195,// Catalan + 203,// Chinese + 211,// Corsican + 220,// Croatian + 229,// Czech + 235,// Danish + 242,// Dutch + 248,// English + 256,// Esperanto + 266,// Estonian + 275,// Faroese + 283,// Fiji + 288,// Finnish + 296,// French + 303,// Frisian + 311,// Gaelic + 318,// Galician + 327,// Georgian + 336,// German + 343,// Greek + 349,// Greenlandic + 361,// Guarani + 369,// Gujarati + 378,// Hausa + 384,// Hebrew + 391,// Hindi + 397,// Hungarian + 407,// Icelandic + 417,// Indonesian + 428,// Interlingua + 440,// Interlingue + 452,// Inuktitut + 462,// Inupiak + 470,// Irish + 476,// Italian + 484,// Japanese + 493,// Javanese + 502,// Kannada + 510,// Kashmiri + 519,// Kazakh + 526,// Kinyarwanda + 538,// Kirghiz + 546,// Korean + 553,// Kurdish + 561,// Kurundi + 569,// Laothian + 578,// Latin + 584,// Latvian + 592,// Lingala + 600,// Lithuanian + 611,// Macedonian + 622,// Malagasy + 631,// Malay + 637,// Malayalam + 647,// Maltese + 655,// Maori + 661,// Marathi + 669,// Moldavian + 679,// Mongolian + 689,// Nauru + 695,// Nepali + 702,// Norwegian + 712,// Occitan + 720,// Oriya + 726,// Pashto + 733,// Persian + 741,// Polish + 748,// Portuguese + 759,// Punjabi + 767,// Quechua + 775,// RhaetoRomance + 789,// Romanian + 798,// Russian + 806,// Samoan + 813,// Sangho + 820,// Sanskrit + 829,// Serbian + 837,// SerboCroatian + 851,// Sesotho + 859,// Setswana + 868,// Shona + 874,// Sindhi + 881,// Singhalese + 892,// Siswati + 900,// Slovak + 907,// Slovenian + 917,// Somali + 924,// Spanish + 932,// Sundanese + 942,// Swahili + 950,// Swedish + 958,// Tagalog + 966,// Tajik + 972,// Tamil + 978,// Tatar + 984,// Telugu + 991,// Thai + 996,// Tibetan + 1004,// Tigrinya + 1013,// Tonga + 1019,// Tsonga + 1026,// Turkish + 1034,// Turkmen + 1042,// Twi + 1046,// Uigur + 1052,// Ukrainian + 1062,// Urdu + 1067,// Uzbek + 1073,// Vietnamese + 1084,// Volapuk + 1092,// Welsh + 1098,// Wolof + 1104,// Xhosa + 1110,// Yiddish + 1118,// Yoruba + 1125,// Zhuang + 1132// Zulu +}; + +static const char country_name_list[] = +"Default\0" +"Afghanistan\0" +"Albania\0" +"Algeria\0" +"AmericanSamoa\0" +"Andorra\0" +"Angola\0" +"Anguilla\0" +"Antarctica\0" +"AntiguaAndBarbuda\0" +"Argentina\0" +"Armenia\0" +"Aruba\0" +"Australia\0" +"Austria\0" +"Azerbaijan\0" +"Bahamas\0" +"Bahrain\0" +"Bangladesh\0" +"Barbados\0" +"Belarus\0" +"Belgium\0" +"Belize\0" +"Benin\0" +"Bermuda\0" +"Bhutan\0" +"Bolivia\0" +"BosniaAndHerzegowina\0" +"Botswana\0" +"BouvetIsland\0" +"Brazil\0" +"BritishIndianOceanTerritory\0" +"BruneiDarussalam\0" +"Bulgaria\0" +"BurkinaFaso\0" +"Burundi\0" +"Cambodia\0" +"Cameroon\0" +"Canada\0" +"CapeVerde\0" +"CaymanIslands\0" +"CentralAfricanRepublic\0" +"Chad\0" +"Chile\0" +"China\0" +"ChristmasIsland\0" +"CocosIslands\0" +"Colombia\0" +"Comoros\0" +"DemocraticRepublicOfCongo\0" +"PeoplesRepublicOfCongo\0" +"CookIslands\0" +"CostaRica\0" +"IvoryCoast\0" +"Croatia\0" +"Cuba\0" +"Cyprus\0" +"CzechRepublic\0" +"Denmark\0" +"Djibouti\0" +"Dominica\0" +"DominicanRepublic\0" +"EastTimor\0" +"Ecuador\0" +"Egypt\0" +"ElSalvador\0" +"EquatorialGuinea\0" +"Eritrea\0" +"Estonia\0" +"Ethiopia\0" +"FalklandIslands\0" +"FaroeIslands\0" +"Fiji\0" +"Finland\0" +"France\0" +"MetropolitanFrance\0" +"FrenchGuiana\0" +"FrenchPolynesia\0" +"FrenchSouthernTerritories\0" +"Gabon\0" +"Gambia\0" +"Georgia\0" +"Germany\0" +"Ghana\0" +"Gibraltar\0" +"Greece\0" +"Greenland\0" +"Grenada\0" +"Guadeloupe\0" +"Guam\0" +"Guatemala\0" +"Guinea\0" +"GuineaBissau\0" +"Guyana\0" +"Haiti\0" +"HeardAndMcDonaldIslands\0" +"Honduras\0" +"HongKong\0" +"Hungary\0" +"Iceland\0" +"India\0" +"Indonesia\0" +"Iran\0" +"Iraq\0" +"Ireland\0" +"Israel\0" +"Italy\0" +"Jamaica\0" +"Japan\0" +"Jordan\0" +"Kazakhstan\0" +"Kenya\0" +"Kiribati\0" +"DemocraticRepublicOfKorea\0" +"RepublicOfKorea\0" +"Kuwait\0" +"Kyrgyzstan\0" +"Lao\0" +"Latvia\0" +"Lebanon\0" +"Lesotho\0" +"Liberia\0" +"LibyanArabJamahiriya\0" +"Liechtenstein\0" +"Lithuania\0" +"Luxembourg\0" +"Macau\0" +"Macedonia\0" +"Madagascar\0" +"Malawi\0" +"Malaysia\0" +"Maldives\0" +"Mali\0" +"Malta\0" +"MarshallIslands\0" +"Martinique\0" +"Mauritania\0" +"Mauritius\0" +"Mayotte\0" +"Mexico\0" +"Micronesia\0" +"Moldova\0" +"Monaco\0" +"Mongolia\0" +"Montserrat\0" +"Morocco\0" +"Mozambique\0" +"Myanmar\0" +"Namibia\0" +"Nauru\0" +"Nepal\0" +"Netherlands\0" +"NetherlandsAntilles\0" +"NewCaledonia\0" +"NewZealand\0" +"Nicaragua\0" +"Niger\0" +"Nigeria\0" +"Niue\0" +"NorfolkIsland\0" +"NorthernMarianaIslands\0" +"Norway\0" +"Oman\0" +"Pakistan\0" +"Palau\0" +"PalestinianTerritory\0" +"Panama\0" +"PapuaNewGuinea\0" +"Paraguay\0" +"Peru\0" +"Philippines\0" +"Pitcairn\0" +"Poland\0" +"Portugal\0" +"PuertoRico\0" +"Qatar\0" +"Reunion\0" +"Romania\0" +"RussianFederation\0" +"Rwanda\0" +"SaintKittsAndNevis\0" +"StLucia\0" +"StVincentAndTheGrenadines\0" +"Samoa\0" +"SanMarino\0" +"SaoTomeAndPrincipe\0" +"SaudiArabia\0" +"Senegal\0" +"Seychelles\0" +"SierraLeone\0" +"Singapore\0" +"Slovakia\0" +"Slovenia\0" +"SolomonIslands\0" +"Somalia\0" +"SouthAfrica\0" +"SouthGeorgiaAndTheSouthSandwichIslands\0" +"Spain\0" +"SriLanka\0" +"StHelena\0" +"StPierreAndMiquelon\0" +"Sudan\0" +"Suriname\0" +"SvalbardAndJanMayenIslands\0" +"Swaziland\0" +"Sweden\0" +"Switzerland\0" +"SyrianArabRepublic\0" +"Taiwan\0" +"Tajikistan\0" +"Tanzania\0" +"Thailand\0" +"Togo\0" +"Tokelau\0" +"Tonga\0" +"TrinidadAndTobago\0" +"Tunisia\0" +"Turkey\0" +"Turkmenistan\0" +"TurksAndCaicosIslands\0" +"Tuvalu\0" +"Uganda\0" +"Ukraine\0" +"UnitedArabEmirates\0" +"UnitedKingdom\0" +"UnitedStates\0" +"UnitedStatesMinorOutlyingIslands\0" +"Uruguay\0" +"Uzbekistan\0" +"Vanuatu\0" +"VaticanCityState\0" +"Venezuela\0" +"VietNam\0" +"BritishVirginIslands\0" +"USVirginIslands\0" +"WallisAndFutunaIslands\0" +"WesternSahara\0" +"Yemen\0" +"Yugoslavia\0" +"Zambia\0" +"Zimbabwe\0"; + +static const uint country_name_index[] = { + 0,// AnyCountry + 8,// Afghanistan + 20,// Albania + 28,// Algeria + 36,// AmericanSamoa + 50,// Andorra + 58,// Angola + 65,// Anguilla + 74,// Antarctica + 85,// AntiguaAndBarbuda + 103,// Argentina + 113,// Armenia + 121,// Aruba + 127,// Australia + 137,// Austria + 145,// Azerbaijan + 156,// Bahamas + 164,// Bahrain + 172,// Bangladesh + 183,// Barbados + 192,// Belarus + 200,// Belgium + 208,// Belize + 215,// Benin + 221,// Bermuda + 229,// Bhutan + 236,// Bolivia + 244,// BosniaAndHerzegowina + 265,// Botswana + 274,// BouvetIsland + 287,// Brazil + 294,// BritishIndianOceanTerritory + 322,// BruneiDarussalam + 339,// Bulgaria + 348,// BurkinaFaso + 360,// Burundi + 368,// Cambodia + 377,// Cameroon + 386,// Canada + 393,// CapeVerde + 403,// CaymanIslands + 417,// CentralAfricanRepublic + 440,// Chad + 445,// Chile + 451,// China + 457,// ChristmasIsland + 473,// CocosIslands + 486,// Colombia + 495,// Comoros + 503,// DemocraticRepublicOfCongo + 529,// PeoplesRepublicOfCongo + 552,// CookIslands + 564,// CostaRica + 574,// IvoryCoast + 585,// Croatia + 593,// Cuba + 598,// Cyprus + 605,// CzechRepublic + 619,// Denmark + 627,// Djibouti + 636,// Dominica + 645,// DominicanRepublic + 663,// EastTimor + 673,// Ecuador + 681,// Egypt + 687,// ElSalvador + 698,// EquatorialGuinea + 715,// Eritrea + 723,// Estonia + 731,// Ethiopia + 740,// FalklandIslands + 756,// FaroeIslands + 769,// Fiji + 774,// Finland + 782,// France + 789,// MetropolitanFrance + 808,// FrenchGuiana + 821,// FrenchPolynesia + 837,// FrenchSouthernTerritories + 863,// Gabon + 869,// Gambia + 876,// Georgia + 884,// Germany + 892,// Ghana + 898,// Gibraltar + 908,// Greece + 915,// Greenland + 925,// Grenada + 933,// Guadeloupe + 944,// Guam + 949,// Guatemala + 959,// Guinea + 966,// GuineaBissau + 979,// Guyana + 986,// Haiti + 992,// HeardAndMcDonaldIslands + 1016,// Honduras + 1025,// HongKong + 1034,// Hungary + 1042,// Iceland + 1050,// India + 1056,// Indonesia + 1066,// Iran + 1071,// Iraq + 1076,// Ireland + 1084,// Israel + 1091,// Italy + 1097,// Jamaica + 1105,// Japan + 1111,// Jordan + 1118,// Kazakhstan + 1129,// Kenya + 1135,// Kiribati + 1144,// DemocraticRepublicOfKorea + 1170,// RepublicOfKorea + 1186,// Kuwait + 1193,// Kyrgyzstan + 1204,// Lao + 1208,// Latvia + 1215,// Lebanon + 1223,// Lesotho + 1231,// Liberia + 1239,// LibyanArabJamahiriya + 1260,// Liechtenstein + 1274,// Lithuania + 1284,// Luxembourg + 1295,// Macau + 1301,// Macedonia + 1311,// Madagascar + 1322,// Malawi + 1329,// Malaysia + 1338,// Maldives + 1347,// Mali + 1352,// Malta + 1358,// MarshallIslands + 1374,// Martinique + 1385,// Mauritania + 1396,// Mauritius + 1406,// Mayotte + 1414,// Mexico + 1421,// Micronesia + 1432,// Moldova + 1440,// Monaco + 1447,// Mongolia + 1456,// Montserrat + 1467,// Morocco + 1475,// Mozambique + 1486,// Myanmar + 1494,// Namibia + 1502,// Nauru + 1508,// Nepal + 1514,// Netherlands + 1526,// NetherlandsAntilles + 1546,// NewCaledonia + 1559,// NewZealand + 1570,// Nicaragua + 1580,// Niger + 1586,// Nigeria + 1594,// Niue + 1599,// NorfolkIsland + 1613,// NorthernMarianaIslands + 1636,// Norway + 1643,// Oman + 1648,// Pakistan + 1657,// Palau + 1663,// PalestinianTerritory + 1684,// Panama + 1691,// PapuaNewGuinea + 1706,// Paraguay + 1715,// Peru + 1720,// Philippines + 1732,// Pitcairn + 1741,// Poland + 1748,// Portugal + 1757,// PuertoRico + 1768,// Qatar + 1774,// Reunion + 1782,// Romania + 1790,// RussianFederation + 1808,// Rwanda + 1815,// SaintKittsAndNevis + 1834,// StLucia + 1842,// StVincentAndTheGrenadines + 1868,// Samoa + 1874,// SanMarino + 1884,// SaoTomeAndPrincipe + 1903,// SaudiArabia + 1915,// Senegal + 1923,// Seychelles + 1934,// SierraLeone + 1946,// Singapore + 1956,// Slovakia + 1965,// Slovenia + 1974,// SolomonIslands + 1989,// Somalia + 1997,// SouthAfrica + 2009,// SouthGeorgiaAndTheSouthSandwichIslands + 2048,// Spain + 2054,// SriLanka + 2063,// StHelena + 2072,// StPierreAndMiquelon + 2092,// Sudan + 2098,// Suriname + 2107,// SvalbardAndJanMayenIslands + 2134,// Swaziland + 2144,// Sweden + 2151,// Switzerland + 2163,// SyrianArabRepublic + 2182,// Taiwan + 2189,// Tajikistan + 2200,// Tanzania + 2209,// Thailand + 2218,// Togo + 2223,// Tokelau + 2231,// Tonga + 2237,// TrinidadAndTobago + 2255,// Tunisia + 2263,// Turkey + 2270,// Turkmenistan + 2283,// TurksAndCaicosIslands + 2305,// Tuvalu + 2312,// Uganda + 2319,// Ukraine + 2327,// UnitedArabEmirates + 2346,// UnitedKingdom + 2360,// UnitedStates + 2373,// UnitedStatesMinorOutlyingIslands + 2406,// Uruguay + 2414,// Uzbekistan + 2425,// Vanuatu + 2433,// VaticanCityState + 2450,// Venezuela + 2460,// VietNam + 2468,// BritishVirginIslands + 2489,// USVirginIslands + 2505,// WallisAndFutunaIslands + 2528,// WesternSahara + 2542,// Yemen + 2548,// Yugoslavia + 2559,// Zambia + 2566// Zimbabwe +}; + +static const char language_code_list[] = +" " // Unused +" " // C +"ab" // Abkhazian +"om" // Afan +"aa" // Afar +"af" // Afrikaans +"sq" // Albanian +"am" // Amharic +"ar" // Arabic +"hy" // Armenian +"as" // Assamese +"ay" // Aymara +"az" // Azerbaijani +"ba" // Bashkir +"eu" // Basque +"bn" // Bengali +"dz" // Bhutani +"bh" // Bihari +"bi" // Bislama +"br" // Breton +"bg" // Bulgarian +"my" // Burmese +"be" // Byelorussian +"km" // Cambodian +"ca" // Catalan +"zh" // Chinese +"co" // Corsican +"hr" // Croatian +"cs" // Czech +"da" // Danish +"nl" // Dutch +"en" // English +"eo" // Esperanto +"et" // Estonian +"fo" // Faroese +"fj" // Fiji +"fi" // Finnish +"fr" // French +"fy" // Frisian +"gd" // Gaelic +"gl" // Galician +"ka" // Georgian +"de" // German +"el" // Greek +"kl" // Greenlandic +"gn" // Guarani +"gu" // Gujarati +"ha" // Hausa +"he" // Hebrew +"hi" // Hindi +"hu" // Hungarian +"is" // Icelandic +"id" // Indonesian +"ia" // Interlingua +"ie" // Interlingue +"iu" // Inuktitut +"ik" // Inupiak +"ga" // Irish +"it" // Italian +"ja" // Japanese +"jv" // Javanese +"kn" // Kannada +"ks" // Kashmiri +"kk" // Kazakh +"rw" // Kinyarwanda +"ky" // Kirghiz +"ko" // Korean +"ku" // Kurdish +"rn" // Kurundi +"lo" // Laothian +"la" // Latin +"lv" // Latvian +"ln" // Lingala +"lt" // Lithuanian +"mk" // Macedonian +"mg" // Malagasy +"ms" // Malay +"ml" // Malayalam +"mt" // Maltese +"mi" // Maori +"mr" // Marathi +"mo" // Moldavian +"mn" // Mongolian +"na" // Nauru +"ne" // Nepali +"no" // Norwegian +"oc" // Occitan +"or" // Oriya +"ps" // Pashto +"fa" // Persian +"pl" // Polish +"pt" // Portuguese +"pa" // Punjabi +"qu" // Quechua +"rm" // RhaetoRomance +"ro" // Romanian +"ru" // Russian +"sm" // Samoan +"sg" // Sangho +"sa" // Sanskrit +"sr" // Serbian +"sh" // SerboCroatian +"st" // Sesotho +"tn" // Setswana +"sn" // Shona +"sd" // Sindhi +"si" // Singhalese +"ss" // Siswati +"sk" // Slovak +"sl" // Slovenian +"so" // Somali +"es" // Spanish +"su" // Sundanese +"sw" // Swahili +"sv" // Swedish +"tl" // Tagalog +"tg" // Tajik +"ta" // Tamil +"tt" // Tatar +"te" // Telugu +"th" // Thai +"bo" // Tibetan +"ti" // Tigrinya +"to" // Tonga +"ts" // Tsonga +"tr" // Turkish +"tk" // Turkmen +"tw" // Twi +"ug" // Uigur +"uk" // Ukrainian +"ur" // Urdu +"uz" // Uzbek +"vi" // Vietnamese +"vo" // Volapuk +"cy" // Welsh +"wo" // Wolof +"xh" // Xhosa +"yi" // Yiddish +"yo" // Yoruba +"za" // Zhuang +"zu" // Zulu +; + +static const char country_code_list[] = +" " // AnyLanguage +"AF" // Afghanistan +"AL" // Albania +"DZ" // Algeria +"AS" // AmericanSamoa +"AD" // Andorra +"AO" // Angola +"AI" // Anguilla +"AQ" // Antarctica +"AG" // AntiguaAndBarbuda +"AR" // Argentina +"AM" // Armenia +"AW" // Aruba +"AU" // Australia +"AT" // Austria +"AZ" // Azerbaijan +"BS" // Bahamas +"BH" // Bahrain +"BD" // Bangladesh +"BB" // Barbados +"BY" // Belarus +"BE" // Belgium +"BZ" // Belize +"BJ" // Benin +"BM" // Bermuda +"BT" // Bhutan +"BO" // Bolivia +"BA" // BosniaAndHerzegowina +"BW" // Botswana +"BV" // BouvetIsland +"BR" // Brazil +"IO" // BritishIndianOceanTerritory +"BN" // BruneiDarussalam +"BG" // Bulgaria +"BF" // BurkinaFaso +"BI" // Burundi +"KH" // Cambodia +"CM" // Cameroon +"CA" // Canada +"CV" // CapeVerde +"KY" // CaymanIslands +"CF" // CentralAfricanRepublic +"TD" // Chad +"CL" // Chile +"CN" // China +"CX" // ChristmasIsland +"CC" // CocosIslands +"CO" // Colombia +"KM" // Comoros +"CD" // DemocraticRepublicOfCongo +"CG" // PeoplesRepublicOfCongo +"CK" // CookIslands +"CR" // CostaRica +"CI" // IvoryCoast +"HR" // Croatia +"CU" // Cuba +"CY" // Cyprus +"CZ" // CzechRepublic +"DK" // Denmark +"DJ" // Djibouti +"DM" // Dominica +"DO" // DominicanRepublic +"TL" // EastTimor +"EC" // Ecuador +"EG" // Egypt +"SV" // ElSalvador +"GQ" // EquatorialGuinea +"ER" // Eritrea +"EE" // Estonia +"ET" // Ethiopia +"FK" // FalklandIslands +"FO" // FaroeIslands +"FJ" // Fiji +"FI" // Finland +"FR" // France +"FX" // MetropolitanFrance +"GF" // FrenchGuiana +"PF" // FrenchPolynesia +"TF" // FrenchSouthernTerritories +"GA" // Gabon +"GM" // Gambia +"GE" // Georgia +"DE" // Germany +"GH" // Ghana +"GI" // Gibraltar +"GR" // Greece +"GL" // Greenland +"GD" // Grenada +"GP" // Guadeloupe +"GU" // Guam +"GT" // Guatemala +"GN" // Guinea +"GW" // GuineaBissau +"GY" // Guyana +"HT" // Haiti +"HM" // HeardAndMcDonaldIslands +"HN" // Honduras +"HK" // HongKong +"HU" // Hungary +"IS" // Iceland +"IN" // India +"ID" // Indonesia +"IR" // Iran +"IQ" // Iraq +"IE" // Ireland +"IL" // Israel +"IT" // Italy +"JM" // Jamaica +"JP" // Japan +"JO" // Jordan +"KZ" // Kazakhstan +"KE" // Kenya +"KI" // Kiribati +"KP" // DemocraticRepublicOfKorea +"KR" // RepublicOfKorea +"KW" // Kuwait +"KG" // Kyrgyzstan +"LA" // Lao +"LV" // Latvia +"LB" // Lebanon +"LS" // Lesotho +"LR" // Liberia +"LY" // LibyanArabJamahiriya +"LI" // Liechtenstein +"LT" // Lithuania +"LU" // Luxembourg +"MO" // Macau +"MK" // Macedonia +"MG" // Madagascar +"MW" // Malawi +"MY" // Malaysia +"MV" // Maldives +"ML" // Mali +"MT" // Malta +"MH" // MarshallIslands +"MQ" // Martinique +"MR" // Mauritania +"MU" // Mauritius +"YT" // Mayotte +"MX" // Mexico +"FM" // Micronesia +"MD" // Moldova +"MC" // Monaco +"MN" // Mongolia +"MS" // Montserrat +"MA" // Morocco +"MZ" // Mozambique +"MM" // Myanmar +"NA" // Namibia +"NR" // Nauru +"NP" // Nepal +"NL" // Netherlands +"AN" // NetherlandsAntilles +"NC" // NewCaledonia +"NZ" // NewZealand +"NI" // Nicaragua +"NE" // Niger +"NG" // Nigeria +"NU" // Niue +"NF" // NorfolkIsland +"MP" // NorthernMarianaIslands +"NO" // Norway +"OM" // Oman +"PK" // Pakistan +"PW" // Palau +"PS" // PalestinianTerritory +"PA" // Panama +"PG" // PapuaNewGuinea +"PY" // Paraguay +"PE" // Peru +"PH" // Philippines +"PN" // Pitcairn +"PL" // Poland +"PT" // Portugal +"PR" // PuertoRico +"QA" // Qatar +"RE" // Reunion +"RO" // Romania +"RU" // RussianFederation +"RW" // Rwanda +"KN" // SaintKittsAndNevis +"LC" // StLucia +"VC" // StVincentAndTheGrenadines +"WS" // Samoa +"SM" // SanMarino +"ST" // SaoTomeAndPrincipe +"SA" // SaudiArabia +"SN" // Senegal +"SC" // Seychelles +"SL" // SierraLeone +"SG" // Singapore +"SK" // Slovakia +"SI" // Slovenia +"SB" // SolomonIslands +"SO" // Somalia +"ZA" // SouthAfrica +"GS" // SouthGeorgiaAndTheSouthSandwichIslands +"ES" // Spain +"LK" // SriLanka +"SH" // StHelena +"PM" // StPierreAndMiquelon +"SD" // Sudan +"SR" // Suriname +"SJ" // SvalbardAndJanMayenIslands +"SZ" // Swaziland +"SE" // Sweden +"CH" // Switzerland +"SY" // SyrianArabRepublic +"TW" // Taiwan +"TJ" // Tajikistan +"TZ" // Tanzania +"TH" // Thailand +"TG" // Togo +"TK" // Tokelau +"TO" // Tonga +"TT" // TrinidadAndTobago +"TN" // Tunisia +"TR" // Turkey +"TM" // Turkmenistan +"TC" // TurksAndCaicosIslands +"TV" // Tuvalu +"UG" // Uganda +"UA" // Ukraine +"AE" // UnitedArabEmirates +"GB" // UnitedKingdom +"US" // UnitedStates +"UM" // UnitedStatesMinorOutlyingIslands +"UY" // Uruguay +"UZ" // Uzbekistan +"VU" // Vanuatu +"VA" // VaticanCityState +"VE" // Venezuela +"VN" // VietNam +"VG" // BritishVirginIslands +"VI" // USVirginIslands +"WF" // WallisAndFutunaIslands +"EH" // WesternSahara +"YE" // Yemen +"YU" // Yugoslavia +"ZM" // Zambia +"ZW" // Zimbabwe +; + +static TQLocale::Language codeToLanguage(const TQString &code) +{ + if (code.length() != 2) + return TQLocale::C; + + ushort uc1 = code.unicode()[0].unicode(); + ushort uc2 = code.unicode()[1].unicode(); + + const char *c = language_code_list; + for (; *c != 0; c += 2) { + if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) + return (TQLocale::Language) ((c - language_code_list)/2); + } + + return TQLocale::C; +} + +static TQLocale::Country codeToCountry(const TQString &code) +{ + if (code.length() != 2) + return TQLocale::AnyCountry; + + ushort uc1 = code.unicode()[0].unicode(); + ushort uc2 = code.unicode()[1].unicode(); + + const char *c = country_code_list; + for (; *c != 0; c += 2) { + if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) + return (TQLocale::Country) ((c - country_code_list)/2); + } + + return TQLocale::AnyCountry; +} + +static TQString languageToCode(TQLocale::Language language) +{ + if (language == TQLocale::C) + return "C"; + + TQString code; + code.setLength(2); + const char *c = language_code_list + 2*(uint)language; + code[0] = c[0]; + code[1] = c[1]; + return code; +} + +static TQString countryToCode(TQLocale::Country country) +{ + if (country == TQLocale::AnyCountry) + return TQString::null; + + TQString code; + code.setLength(2); + const char *c = country_code_list + 2*(uint)country; + code[0] = c[0]; + code[1] = c[1]; + return code; +} + +const TQLocalePrivate *TQLocale::default_d = 0; + +TQString TQLocalePrivate::infinity() const +{ + return TQString::fromLatin1("inf"); +} + +TQString TQLocalePrivate::nan() const +{ + return TQString::fromLatin1("nan"); +} + +#if defined(Q_OS_WIN) +/* Win95 doesn't have a function to return the ISO lang/country name of the user's locale. + Instead it can return a "Windows code". This maps windows codes to ISO country names. */ + +struct WindowsToISOListElt { + int windows_code; + char iso_name[6]; +}; + +static const WindowsToISOListElt windows_to_iso_list[] = { + { 0x0401, "ar_SA" }, + { 0x0402, "bg\0 " }, + { 0x0403, "ca\0 " }, + { 0x0404, "zh_TW" }, + { 0x0405, "cs\0 " }, + { 0x0406, "da\0 " }, + { 0x0407, "de\0 " }, + { 0x0408, "el\0 " }, + { 0x0409, "en_US" }, + { 0x040a, "es\0 " }, + { 0x040b, "fi\0 " }, + { 0x040c, "fr\0 " }, + { 0x040d, "he\0 " }, + { 0x040e, "hu\0 " }, + { 0x040f, "is\0 " }, + { 0x0410, "it\0 " }, + { 0x0411, "ja\0 " }, + { 0x0412, "ko\0 " }, + { 0x0413, "nl\0 " }, + { 0x0414, "no\0 " }, + { 0x0415, "pl\0 " }, + { 0x0416, "pt_BR" }, + { 0x0418, "ro\0 " }, + { 0x0419, "ru\0 " }, + { 0x041a, "hr\0 " }, + { 0x041c, "sq\0 " }, + { 0x041d, "sv\0 " }, + { 0x041e, "th\0 " }, + { 0x041f, "tr\0 " }, + { 0x0420, "ur\0 " }, + { 0x0421, "in\0 " }, + { 0x0422, "uk\0 " }, + { 0x0423, "be\0 " }, + { 0x0425, "et\0 " }, + { 0x0426, "lv\0 " }, + { 0x0427, "lt\0 " }, + { 0x0429, "fa\0 " }, + { 0x042a, "vi\0 " }, + { 0x042d, "eu\0 " }, + { 0x042f, "mk\0 " }, + { 0x0436, "af\0 " }, + { 0x0438, "fo\0 " }, + { 0x0439, "hi\0 " }, + { 0x043e, "ms\0 " }, + { 0x0458, "mt\0 " }, + { 0x0801, "ar_IQ" }, + { 0x0804, "zh_CN" }, + { 0x0807, "de_CH" }, + { 0x0809, "en_GB" }, + { 0x080a, "es_MX" }, + { 0x080c, "fr_BE" }, + { 0x0810, "it_CH" }, + { 0x0812, "ko\0 " }, + { 0x0813, "nl_BE" }, + { 0x0814, "no\0 " }, + { 0x0816, "pt\0 " }, + { 0x081a, "sr\0 " }, + { 0x081d, "sv_FI" }, + { 0x0c01, "ar_EG" }, + { 0x0c04, "zh_HK" }, + { 0x0c07, "de_AT" }, + { 0x0c09, "en_AU" }, + { 0x0c0a, "es\0 " }, + { 0x0c0c, "fr_CA" }, + { 0x0c1a, "sr\0 " }, + { 0x1001, "ar_LY" }, + { 0x1004, "zh_SG" }, + { 0x1007, "de_LU" }, + { 0x1009, "en_CA" }, + { 0x100a, "es_GT" }, + { 0x100c, "fr_CH" }, + { 0x1401, "ar_DZ" }, + { 0x1407, "de_LI" }, + { 0x1409, "en_NZ" }, + { 0x140a, "es_CR" }, + { 0x140c, "fr_LU" }, + { 0x1801, "ar_MA" }, + { 0x1809, "en_IE" }, + { 0x180a, "es_PA" }, + { 0x1c01, "ar_TN" }, + { 0x1c09, "en_ZA" }, + { 0x1c0a, "es_DO" }, + { 0x2001, "ar_OM" }, + { 0x2009, "en_JM" }, + { 0x200a, "es_VE" }, + { 0x2401, "ar_YE" }, + { 0x2409, "en\0 " }, + { 0x240a, "es_CO" }, + { 0x2801, "ar_SY" }, + { 0x2809, "en_BZ" }, + { 0x280a, "es_PE" }, + { 0x2c01, "ar_JO" }, + { 0x2c09, "en_TT" }, + { 0x2c0a, "es_AR" }, + { 0x3001, "ar_LB" }, + { 0x300a, "es_EC" }, + { 0x3401, "ar_KW" }, + { 0x340a, "es_CL" }, + { 0x3801, "ar_AE" }, + { 0x380a, "es_UY" }, + { 0x3c01, "ar_BH" }, + { 0x3c0a, "es_PY" }, + { 0x4001, "ar_QA" }, + { 0x400a, "es_BO" }, + { 0x440a, "es_SV" }, + { 0x480a, "es_HN" }, + { 0x4c0a, "es_NI" }, + { 0x500a, "es_PR" } +}; + +static const int windows_to_iso_count + = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt); + +static const char *winLangCodeToIsoName(int code) +{ + int cmp = code - windows_to_iso_list[0].windows_code; + if (cmp < 0) + return 0; + + if (cmp == 0) + return windows_to_iso_list[0].iso_name; + + int begin = 0; + int end = windows_to_iso_count; + + while (end - begin > 1) { + uint mid = (begin + end)/2; + + const WindowsToISOListElt *elt = windows_to_iso_list + mid; + int cmp = code - elt->windows_code; + if (cmp < 0) + end = mid; + else if (cmp > 0) + begin = mid; + else + return elt->iso_name; + } + + return 0; + +} +#endif // Q_OS_WIN + +const char* TQLocalePrivate::systemLocaleName() +{ + static TQCString lang; + lang = getenv( "LANG" ); + +#if defined( Q_OS_MAC ) + if ( !lang.isEmpty() ) + return lang; + + char mac_ret[255]; + if(!LocaleRefGetPartString(NULL, kLocaleLanguageMask | kLocaleRegionMask, 255, mac_ret)) + lang = mac_ret; +#endif + +#if defined(TQ_WS_WIN) + if ( !lang.isEmpty() ) { + long id = 0; + bool ok = false; + id = qstrtoll(lang.data(), 0, 0, &ok); + if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) + return lang; + else + return winLangCodeToIsoName( (int)id ); + } + + if (qWinVersion() == TQt::WV_95) { + lang = winLangCodeToIsoName(GetUserDefaultLangID()); + } else { + QT_WA( { + wchar_t out[256]; + TQString language; + TQString sublanguage; + if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME , out, 255 ) ) + language = TQString::fromUcs2( (ushort*)out ); + if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) + sublanguage = TQString::fromUcs2( (ushort*)out ).lower(); + lang = language; + if ( sublanguage != language && !sublanguage.isEmpty() ) + lang += "_" + sublanguage.upper(); + } , { + char out[256]; + TQString language; + TQString sublanguage; + if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, out, 255 ) ) + language = TQString::fromLocal8Bit( out ); + if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) + sublanguage = TQString::fromLocal8Bit( out ).lower(); + lang = language; + if ( sublanguage != language && !sublanguage.isEmpty() ) + lang += "_" + sublanguage.upper(); + } ); + } +#endif + if ( lang.isEmpty() ) + lang = "C"; + + return lang; +} + +static const TQLocalePrivate *findLocale(TQLocale::Language language, + TQLocale::Country country) +{ + unsigned language_id = (unsigned)language; + unsigned country_id = (unsigned)country; + + uint idx = locale_index[language_id]; + + const TQLocalePrivate *d = locale_data + idx; + + if (idx == 0) // default language has no associated country + return d; + + if (country == TQLocale::AnyCountry) + return d; + + Q_ASSERT(d->languageId() == language_id); + + while (d->languageId() == language_id + && d->countryId() != country_id) + ++d; + + if (d->countryId() == country_id + && d->languageId() == language_id) + return d; + + return locale_data + idx; +} + +/*! + \class TQLocale + \brief The TQLocale class converts between numbers and their + string representations in various languages. + + \reentrant + \ingroup text + + It is initialized with a country/language pair in its constructor + and offers number-to-string and string-to-number conversion + functions simmilar to those in TQString. + + \code + TQLocale egyptian(TQLocale::Arabic, TQLocale::Egypt); + TQString s1 = egyptian.toString(1.571429E+07, 'e'); + TQString s2 = egyptian.toString(10); + + double d = egyptian.toDouble(s1); + int s2 = egyptian.toInt(s2); + \endcode + + TQLocale supports the concept of a default locale, which is + determined from the system's locale settings at application + startup. The default locale can be changed by calling the + static member setDefault(). The default locale has the + following effects: + + \list + \i If a TQLocale object is constructed with the default constructor, + it will use the default locale's settings. + \i TQString::toDouble() interprets the string according to the default + locale. If this fails, it falls back on the "C" locale. + \i TQString::arg() uses the default locale to format a number when + its position specifier in the format string contains an 'L', + e.g. "%L1". + \endlist + + \code + TQLocale::setDefault(TQLocale(TQLocale::Hebrew, TQLocale::Israel)); + TQLocale hebrew; // Constructs a default TQLocale + TQString s1 = hebrew.toString(15714.3, 'e'); + + bool ok; + double d; + + TQLocale::setDefault(TQLocale::C); + d = TQString( "1234,56" ).toDouble(&ok); // ok == false + d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + + TQLocale::setDefault(TQLocale::German); + d = TQString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56 + d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + + TQLocale::setDefault(TQLocale(TQLocale::English, TQLocale::UnitedStates)); + str = TQString( "%1 %L2 %L3" ) + .arg( 12345 ) + .arg( 12345 ) + .arg( 12345, 0, 16 ); + // str == "12345 12,345 3039" + \endcode + + When a language/country pair is specified in the constructor, one + of three things can happen: + + \list + \i If the language/country pair is found in the database, it is used. + \i If the language is found but the country is not, or if the country + is \c AnyCountry, the language is used with the most + appropriate available country (for example, Germany for German), + \i If neither the language nor the country are found, TQLocale + defaults to the default locale (see setDefault()). + \endlist + + The "C" locale is identical to English/UnitedStates. + + Use language() and country() to determine the actual language and + country values used. + + An alternative method for constructing a TQLocale object is by + specifying the locale name. + + \code + TQLocale korean("ko"); + TQLocale swiss("de_CH"); + \endcode + + This constructor converts the locale name to a language/country + pair; it does not use the system locale database. + + All the methods in TQLocale, with the exception of setDefault(), + are reentrant. + + \sa TQString::toDouble() TQString::arg() + + The double-to-string and string-to-double conversion functions are + covered by the following licenses: + + \legalese + + Copyright (c) 1991 by AT&T. + + Permission to use, copy, modify, and distribute this software for any + purpose without fee is hereby granted, provided that this entire notice + is included in all copies of any software which is or includes a copy + or modification of this software and in all copies of the supporting + documentation for such software. + + THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY + REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + + This product includes software developed by the University of + California, Berkeley and its contributors. +*/ + +/*! + \enum TQLocale::Language + + This enumerated type is used to specify a language. + + \value C Identical to English/UnitedStates + \value Abkhazian + \value Afan + \value Afar + \value Afrikaans + \value Albanian + \value Amharic + \value Arabic + \value Armenian + \value Assamese + \value Aymara + \value Azerbaijani + \value Bashkir + \value Basque + \value Bengali + \value Bhutani + \value Bihari + \value Bislama + \value Breton + \value Bulgarian + \value Burmese + \value Byelorussian + \value Cambodian + \value Catalan + \value Chinese + \value Corsican + \value Croatian + \value Czech + \value Danish + \value Dutch + \value English + \value Esperanto + \value Estonian + \value Faroese + \value FijiLanguage + \value Finnish + \value French + \value Frisian + \value Gaelic + \value Galician + \value Georgian + \value German + \value Greek + \value Greenlandic + \value Guarani + \value Gujarati + \value Hausa + \value Hebrew + \value Hindi + \value Hungarian + \value Icelandic + \value Indonesian + \value Interlingua + \value Interlingue + \value Inuktitut + \value Inupiak + \value Irish + \value Italian + \value Japanese + \value Javanese + \value Kannada + \value Kashmiri + \value Kazakh + \value Kinyarwanda + \value Kirghiz + \value Korean + \value Kurdish + \value Kurundi + \value Laothian + \value Latin + \value Latvian + \value Lingala + \value Lithuanian + \value Macedonian + \value Malagasy + \value Malay + \value Malayalam + \value Maltese + \value Maori + \value Marathi + \value Moldavian + \value Mongolian + \value NauruLanguage + \value Nepali + \value Norwegian + \value Occitan + \value Oriya + \value Pashto + \value Persian + \value Polish + \value Portuguese + \value Punjabi + \value Quechua + \value RhaetoRomance + \value Romanian + \value Russian + \value Samoan + \value Sangho + \value Sanskrit + \value Serbian + \value SerboCroatian + \value Sesotho + \value Setswana + \value Shona + \value Sindhi + \value Singhalese + \value Siswati + \value Slovak + \value Slovenian + \value Somali + \value Spanish + \value Sundanese + \value Swahili + \value Swedish + \value Tagalog + \value Tajik + \value Tamil + \value Tatar + \value Telugu + \value Thai + \value Tibetan + \value Tigrinya + \value TongaLanguage + \value Tsonga + \value Turkish + \value Turkmen + \value Twi + \value Uigur + \value Ukrainian + \value Urdu + \value Uzbek + \value Vietnamese + \value Volapuk + \value Welsh + \value Wolof + \value Xhosa + \value Yiddish + \value Yoruba + \value Zhuang + \value Zulu +*/ + +/*! + \enum TQLocale::Country + + This enumerated type is used to specify a country. + + \value AnyCountry + \value Afghanistan + \value Albania + \value Algeria + \value AmericanSamoa + \value Andorra + \value Angola + \value Anguilla + \value Antarctica + \value AntiguaAndBarbuda + \value Argentina + \value Armenia + \value Aruba + \value Australia + \value Austria + \value Azerbaijan + \value Bahamas + \value Bahrain + \value Bangladesh + \value Barbados + \value Belarus + \value Belgium + \value Belize + \value Benin + \value Bermuda + \value Bhutan + \value Bolivia + \value BosniaAndHerzegowina + \value Botswana + \value BouvetIsland + \value Brazil + \value BritishIndianOceanTerritory + \value BruneiDarussalam + \value Bulgaria + \value BurkinaFaso + \value Burundi + \value Cambodia + \value Cameroon + \value Canada + \value CapeVerde + \value CaymanIslands + \value CentralAfricanRepublic + \value Chad + \value Chile + \value China + \value ChristmasIsland + \value CocosIslands + \value Colombia + \value Comoros + \value DemocraticRepublicOfCongo + \value PeoplesRepublicOfCongo + \value CookIslands + \value CostaRica + \value IvoryCoast + \value Croatia + \value Cuba + \value Cyprus + \value CzechRepublic + \value Denmark + \value Djibouti + \value Dominica + \value DominicanRepublic + \value EastTimor + \value Ecuador + \value Egypt + \value ElSalvador + \value EquatorialGuinea + \value Eritrea + \value Estonia + \value Ethiopia + \value FalklandIslands + \value FaroeIslands + \value FijiCountry + \value Finland + \value France + \value MetropolitanFrance + \value FrenchGuiana + \value FrenchPolynesia + \value FrenchSouthernTerritories + \value Gabon + \value Gambia + \value Georgia + \value Germany + \value Ghana + \value Gibraltar + \value Greece + \value Greenland + \value Grenada + \value Guadeloupe + \value Guam + \value Guatemala + \value Guinea + \value GuineaBissau + \value Guyana + \value Haiti + \value HeardAndMcDonaldIslands + \value Honduras + \value HongKong + \value Hungary + \value Iceland + \value India + \value Indonesia + \value Iran + \value Iraq + \value Ireland + \value Israel + \value Italy + \value Jamaica + \value Japan + \value Jordan + \value Kazakhstan + \value Kenya + \value Kiribati + \value DemocraticRepublicOfKorea + \value RepublicOfKorea + \value Kuwait + \value Kyrgyzstan + \value Lao + \value Latvia + \value Lebanon + \value Lesotho + \value Liberia + \value LibyanArabJamahiriya + \value Liechtenstein + \value Lithuania + \value Luxembourg + \value Macau + \value Macedonia + \value Madagascar + \value Malawi + \value Malaysia + \value Maldives + \value Mali + \value Malta + \value MarshallIslands + \value Martinique + \value Mauritania + \value Mauritius + \value Mayotte + \value Mexico + \value Micronesia + \value Moldova + \value Monaco + \value Mongolia + \value Montserrat + \value Morocco + \value Mozambique + \value Myanmar + \value Namibia + \value NauruCountry + \value Nepal + \value Netherlands + \value NetherlandsAntilles + \value NewCaledonia + \value NewZealand + \value Nicaragua + \value Niger + \value Nigeria + \value Niue + \value NorfolkIsland + \value NorthernMarianaIslands + \value Norway + \value Oman + \value Pakistan + \value Palau + \value PalestinianTerritory + \value Panama + \value PapuaNewGuinea + \value Paraguay + \value Peru + \value Philippines + \value Pitcairn + \value Poland + \value Portugal + \value PuertoRico + \value Qatar + \value Reunion + \value Romania + \value RussianFederation + \value Rwanda + \value SaintKittsAndNevis + \value StLucia + \value StVincentAndTheGrenadines + \value Samoa + \value SanMarino + \value SaoTomeAndPrincipe + \value SaudiArabia + \value Senegal + \value Seychelles + \value SierraLeone + \value Singapore + \value Slovakia + \value Slovenia + \value SolomonIslands + \value Somalia + \value SouthAfrica + \value SouthGeorgiaAndTheSouthSandwichIslands + \value Spain + \value SriLanka + \value StHelena + \value StPierreAndMiquelon + \value Sudan + \value Suriname + \value SvalbardAndJanMayenIslands + \value Swaziland + \value Sweden + \value Switzerland + \value SyrianArabRepublic + \value Taiwan + \value Tajikistan + \value Tanzania + \value Thailand + \value Togo + \value Tokelau + \value TongaCountry + \value TrinidadAndTobago + \value Tunisia + \value Turkey + \value Turkmenistan + \value TurksAndCaicosIslands + \value Tuvalu + \value Uganda + \value Ukraine + \value UnitedArabEmirates + \value UnitedKingdom + \value UnitedStates + \value UnitedStatesMinorOutlyingIslands + \value Uruguay + \value Uzbekistan + \value Vanuatu + \value VaticanCityState + \value Venezuela + \value VietNam + \value BritishVirginIslands + \value USVirginIslands + \value WallisAndFutunaIslands + \value WesternSahara + \value Yemen + \value Yugoslavia + \value Zambia + \value Zimbabwe +*/ + +/*! + Constructs a TQLocale object with the specified \a name, + which has the format + "language[_country][.codeset][@modifier]" or "C", where: + + \list + \i language is a lowercase, two-letter, ISO 639 language code, + \i territory is an uppercase, two-letter, ISO 3166 country code, + \i and codeset and modifier are ignored. + \endlist + + If the string violates the locale format, or language is not + a valid ISO 369 code, the "C" locale is used instead. If country + is not present, or is not a valid ISO 3166 code, the most + appropriate country is chosen for the specified language. + + The language and country codes are converted to their respective + \c Language and \c Country enums. After this conversion is + performed the constructor behaves exactly like TQLocale(Country, + Language). + + This constructor is much slower than TQLocale(Country, Language). + + \sa name() +*/ + +TQLocale::TQLocale(const TQString &name) +{ + Language lang = C; + Country cntry = AnyCountry; + + uint l = name.length(); + + do { + if (l < 2) + break; + + const TQChar *uc = name.unicode(); + if (l > 2 + && uc[2] != '_' + && uc[2] != '.' + && uc[2] != '@') + break; + + lang = codeToLanguage(name.mid(0, 2)); + if (lang == C) + break; + + if (l == 2 || uc[2] == '.' || uc[2] == '@') + break; + + // we have uc[2] == '_' + if (l < 5) + break; + + if (l > 5 && uc[5] != '.' && uc[5] != '@') + break; + + cntry = codeToCountry(name.mid(3, 2)); + } while (FALSE); + + d = findLocale(lang, cntry); +} + +/*! + Constructs a TQLocale object initialized with the default locale. + + \sa setDefault() +*/ + +TQLocale::TQLocale() +{ + if (default_d == 0) + default_d = system().d; + + d = default_d; +} + +/*! + Constructs a TQLocale object with the specified \a language and \a + country. + + \list + \i If the language/country pair is found in the database, it is used. + \i If the language is found but the country is not, or if the country + is \c AnyCountry, the language is used with the most + appropriate available country (for example, Germany for German), + \i If neither the language nor the country are found, TQLocale + defaults to the default locale (see setDefault()). + \endlist + + The language and country that are actually used can be queried + using language() and country(). + + \sa setDefault() language() country() +*/ + +TQLocale::TQLocale(Language language, Country country) +{ + d = findLocale(language, country); + + // If not found, should default to system + if (d->languageId() == TQLocale::C && language != TQLocale::C) { + if (default_d == 0) + default_d = system().d; + + d = default_d; + } +} + +/*! + Constructs a TQLocale object as a copy of \a other. +*/ + +TQLocale::TQLocale(const TQLocale &other) +{ + d = other.d; +} + +/*! + Assigns \a other to this TQLocale object and returns a reference + to this TQLocale object. +*/ + +TQLocale &TQLocale::operator=(const TQLocale &other) +{ + d = other.d; + return *this; +} + +/*! + \nonreentrant + + Sets the global default locale to \a locale. These + values are used when a TQLocale object is constructed with + no arguments. If this function is not called, the system's + locale is used. + + \warning In a multithreaded application, the default locale + should be set at application startup, before any non-GUI threads + are created. + + \sa system() c() +*/ + +void TQLocale::setDefault(const TQLocale &locale) +{ + default_d = locale.d; +} + +/*! + Returns the language of this locale. + + \sa TQLocale() +*/ +TQLocale::Language TQLocale::language() const +{ + return (Language)d->languageId(); +} + +/*! + Returns the country of this locale. + + \sa TQLocale() +*/ +TQLocale::Country TQLocale::country() const +{ + return (Country)d->countryId(); +} + +/*! + Returns the language and country of this locale as a + string of the form "language_country", where + language is a lowercase, two-letter ISO 639 language code, + and country is an uppercase, two-letter ISO 3166 country code. + + \sa TQLocale() +*/ + +TQString TQLocale::name() const +{ + Language l = language(); + + TQString result = languageToCode(l); + + if (l == C) + return result; + + Country c = country(); + if (c == AnyCountry) + return result; + + result.append('_'); + result.append(countryToCode(c)); + + return result; +} + +/*! + Returns a TQString containing the name of \a language. +*/ + +TQString TQLocale::languageToString(Language language) +{ + if ((uint)language > (uint)TQLocale::LastLanguage) + return "Unknown"; + return language_name_list + language_name_index[(uint)language]; +} + +/*! + Returns a TQString containing the name of \a country. +*/ + +TQString TQLocale::countryToString(Country country) +{ + if ((uint)country > (uint)TQLocale::LastCountry) + return "Unknown"; + return country_name_list + country_name_index[(uint)country]; +} + +/*! + Returns the short int represented by the localized string \a s, or + 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +short TQLocale::toShort(const TQString &s, bool *ok) const +{ + TQ_LLONG i = toLongLong(s, ok); + if (i < SHRT_MIN || i > SHRT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (short) i; +} + +/*! + Returns the unsigned short int represented by the localized string + \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +ushort TQLocale::toUShort(const TQString &s, bool *ok) const +{ + TQ_ULLONG i = toULongLong(s, ok); + if (i > USHRT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (ushort) i; +} + +/*! + Returns the int represented by the localized string \a s, or 0 if + the conversion failed. + + If \a ok is not 0, reports failure by setting *ok to false and + success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +int TQLocale::toInt(const TQString &s, bool *ok) const +{ + TQ_LLONG i = toLongLong(s, ok); + if (i < INT_MIN || i > INT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (int) i; +} + +/*! + Returns the unsigned int represented by the localized string \a s, + or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +uint TQLocale::toUInt(const TQString &s, bool *ok) const +{ + TQ_ULLONG i = toULongLong(s, ok); + if (i > UINT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (uint) i; +} + +/*! + Returns the long int represented by the localized string \a s, or + 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +TQ_LONG TQLocale::toLong(const TQString &s, bool *ok) const +{ + TQ_LLONG i = toLongLong(s, ok); + if (i < LONG_MIN || i > LONG_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (TQ_LONG) i; +} + +/*! + Returns the unsigned long int represented by the localized string + \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +TQ_ULONG TQLocale::toULong(const TQString &s, bool *ok) const +{ + TQ_ULLONG i = toULongLong(s, ok); + if (i > ULONG_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (TQ_ULONG) i; +} + +/*! + Returns the long long int represented by the localized string \a + s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + + +TQ_LLONG TQLocale::toLongLong(const TQString &s, bool *ok) const +{ + return d->stringToLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns the unsigned long long int represented by the localized + string \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + + +TQ_ULLONG TQLocale::toULongLong(const TQString &s, bool *ok) const +{ + return d->stringToUnsLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns the float represented by the localized string \a s, or 0.0 + if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +#define QT_MAX_FLOAT 3.4028234663852886e+38 + +float TQLocale::toFloat(const TQString &s, bool *ok) const +{ + bool myOk; + double d = toDouble(s, &myOk); + if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + if (ok != 0) + *ok = TRUE; + return (float) d; +} + +/*! + Returns the double represented by the localized string \a s, or + 0.0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + Unlike TQString::toDouble(), this function does not fall back to + the "C" locale if the string cannot be interpreted in this + locale. + + \code + bool ok; + double d; + + TQLocale c(TQLocale::C); + d = c.toDouble( "1234.56", &ok ); // ok == true, d == 1234.56 + d = c.toDouble( "1,234.56", &ok ); // ok == true, d == 1234.56 + d = c.toDouble( "1234,56", &ok ); // ok == false + + TQLocale german(TQLocale::German); + d = german.toDouble( "1234,56", &ok ); // ok == true, d == 1234.56 + d = german.toDouble( "1.234,56", &ok ); // ok == true, d == 1234.56 + d = german.toDouble( "1234.56", &ok ); // ok == false + + d = german.toDouble( "1.234", &ok ); // ok == true, d == 1234.0 + \endcode + + Notice that the last conversion returns 1234.0, because '.' is the + thousands group separator in the German locale. + + This function ignores leading and trailing whitespace. + + \sa toString() TQString::toDouble() +*/ + +double TQLocale::toDouble(const TQString &s, bool *ok) const +{ + return d->stringToDouble(s, ok, TQLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns a localized string representation of \a i. + + \sa toLongLong() +*/ + +TQString TQLocale::toString(TQ_LLONG i) const +{ + return d->longLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); +} + +/*! + \overload + + \sa toULongLong() +*/ + +TQString TQLocale::toString(TQ_ULLONG i) const +{ + return d->unsLongLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); +} + +static bool qIsUpper(char c) +{ + return c >= 'A' && c <= 'Z'; +} + +static char qToLower(char c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + else + return c; +} + +/*! + \overload + + \a f and \a prec have the same meaning as in TQString::number(double, char, int). + + \sa toDouble() +*/ + +TQString TQLocale::toString(double i, char f, int prec) const +{ + TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal; + uint flags = 0; + + if (qIsUpper(f)) + flags = TQLocalePrivate::CapitalEorX; + f = qToLower(f); + + switch (f) { + case 'f': + form = TQLocalePrivate::DFDecimal; + break; + case 'e': + form = TQLocalePrivate::DFExponent; + break; + case 'g': + form = TQLocalePrivate::DFSignificantDigits; + break; + default: + break; + } + + flags |= TQLocalePrivate::ThousandsGroup; + return d->doubleToString(i, prec, form, -1, flags); +} + +/*! + \fn TQLocale TQLocale::c() + + Returns a TQLocale object initialized to the "C" locale. + + \sa system() +*/ + +/*! + Returns a TQLocale object initialized to the system locale. +*/ + +TQLocale TQLocale::system() +{ +#ifdef Q_OS_UNIX + const char *s = getenv("LC_NUMERIC"); + if (s == 0) + s = getenv("LC_ALL"); + if (s != 0) + return TQLocale(s); +#endif + return TQLocale(TQLocalePrivate::systemLocaleName()); +} + +/*! +\fn TQString TQLocale::toString(short i) const + +\overload + +\sa toShort() +*/ + +/*! +\fn TQString TQLocale::toString(ushort i) const + +\overload + +\sa toUShort() +*/ + +/*! +\fn TQString TQLocale::toString(int i) const + +\overload + +\sa toInt() +*/ + +/*! +\fn TQString TQLocale::toString(uint i) const + +\overload + +\sa toUInt() +*/ + +/*! +\fn TQString TQLocale::toString(TQ_LONG i) const + +\overload + +\sa toLong() +*/ + +/*! +\fn TQString TQLocale::toString(TQ_ULONG i) const + +\overload + +\sa toULong() +*/ + +/*! +\fn TQString TQLocale::toString(float i, char f = 'g', int prec = 6) const + +\overload + +\a f and \a prec have the same meaning as in TQString::number(double, char, int). + +\sa toDouble() +*/ + + +bool TQLocalePrivate::isDigit(TQChar d) const +{ + return zero().unicode() <= d.unicode() + && zero().unicode() + 10 > d.unicode(); +} + +static char digitToCLocale(TQChar zero, TQChar d) +{ + if (zero.unicode() <= d.unicode() + && zero.unicode() + 10 > d.unicode()) + return '0' + d.unicode() - zero.unicode(); + + tqWarning("TQLocalePrivate::digitToCLocale(): bad digit: row=%d, cell=%d", d.row(), d.cell()); + return TQChar(0); +} + +static TQString qulltoa(TQ_ULLONG l, int base, const TQLocalePrivate &locale) +{ + TQChar buff[65]; // length of MAX_ULLONG in base 2 + TQChar *p = buff + 65; + + if (base != 10 || locale.zero().unicode() == '0') { + while (l != 0) { + int c = l % base; + + --p; + + if (c < 10) + *p = '0' + c; + else + *p = c - 10 + 'a'; + + l /= base; + } + } + else { + while (l != 0) { + int c = l % base; + + *(--p) = locale.zero().unicode() + c; + + l /= base; + } + } + + return TQString(p, 65 - (p - buff)); +} + +static TQString qlltoa(TQ_LLONG l, int base, const TQLocalePrivate &locale) +{ + return qulltoa(l < 0 ? -l : l, base, locale); +} + +enum PrecisionMode { + PMDecimalDigits = 0x01, + PMSignificantDigits = 0x02, + PMChopTrailingZeros = 0x03 +}; + +static TQString &decimalForm(TQString &digits, int decpt, uint precision, + PrecisionMode pm, + bool always_show_decpt, + bool thousands_group, + const TQLocalePrivate &locale) +{ + if (decpt < 0) { + for (int i = 0; i < -decpt; ++i) + digits.prepend(locale.zero()); + decpt = 0; + } + else if ((uint)decpt > digits.length()) { + for (uint i = digits.length(); i < (uint)decpt; ++i) + digits.append(locale.zero()); + } + + if (pm == PMDecimalDigits) { + uint decimal_digits = digits.length() - decpt; + for (uint i = decimal_digits; i < precision; ++i) + digits.append(locale.zero()); + } + else if (pm == PMSignificantDigits) { + for (uint i = digits.length(); i < precision; ++i) + digits.append(locale.zero()); + } + else { // pm == PMChopTrailingZeros + } + + if (always_show_decpt || (uint)decpt < digits.length()) + digits.insert(decpt, locale.decimal()); + + if (thousands_group) { + for (int i = decpt - 3; i > 0; i -= 3) + digits.insert(i, locale.group()); + } + + if (decpt == 0) + digits.prepend(locale.zero()); + + return digits; +} + +static TQString &exponentForm(TQString &digits, int decpt, uint precision, + PrecisionMode pm, + bool always_show_decpt, + const TQLocalePrivate &locale) +{ + int exp = decpt - 1; + + if (pm == PMDecimalDigits) { + for (uint i = digits.length(); i < precision + 1; ++i) + digits.append(locale.zero()); + } + else if (pm == PMSignificantDigits) { + for (uint i = digits.length(); i < precision; ++i) + digits.append(locale.zero()); + } + else { // pm == PMChopTrailingZeros + } + + if (always_show_decpt || digits.length() > 1) + digits.insert(1, locale.decimal()); + + digits.append(locale.exponential()); + digits.append(locale.longLongToString(exp, 2, 10, + -1, TQLocalePrivate::AlwaysShowSign)); + + return digits; +} + +static bool isZero(double d) +{ + uchar *ch = (uchar *)&d; + if (ByteOrder == BigEndian) { + return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]); + } else { + return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]); + } +} + +TQString TQLocalePrivate::doubleToString(double d, + int precision, + DoubleForm form, + int width, + unsigned flags) const +{ + if (precision == -1) + precision = 6; + if (width == -1) + width = 0; + + bool negative = FALSE; + bool special_number = FALSE; // nan, +/-inf + TQString num_str; + +#ifdef Q_OS_WIN + // Detect special numbers (nan, +/-inf) + if (qIsInf(d)) { + num_str = infinity(); + special_number = TRUE; + negative = d < 0; + } else if (qIsNan(d)) { + num_str = nan(); + special_number = TRUE; + } +#else + // Comparing directly to INFINITY gives weird results on some systems. + double tmp_infinity = INFINITY; + + // Detect special numbers (nan, +/-inf) + if (d == tmp_infinity || d == -tmp_infinity) { + num_str = infinity(); + special_number = TRUE; + negative = d < 0; + } else if (qIsNan(d)) { + num_str = nan(); + special_number = TRUE; + } +#endif + + // Handle normal numbers + if (!special_number) { + int decpt, sign; + TQString digits; + +#ifdef QT_QLOCALE_USES_FCVT +#ifdef TQT_THREAD_SUPPORT + static bool dummy_for_mutex; + TQMutex *fcvt_mutex = tqt_global_mutexpool ? tqt_global_mutexpool->get( &dummy_for_mutex ) : 0; +# define FCVT_LOCK if (fcvt_mutex) fcvt_mutex->lock() +# define FCVT_UNLOCK if (fcvt_mutex) fcvt_mutex->unlock() +#else +# define FCVT_LOCK +# define FCVT_UNLOCK +#endif + if (form == DFDecimal) { + FCVT_LOCK; + digits = fcvt(d, precision, &decpt, &sign); + FCVT_UNLOCK; + } else { + int pr = precision; + if (form == DFExponent) + ++pr; + else if (form == DFSignificantDigits && pr == 0) + pr = 1; + FCVT_LOCK; + digits = ecvt(d, pr, &decpt, &sign); + FCVT_UNLOCK; + + // Chop trailing zeros + if (digits.length() > 0) { + int last_nonzero_idx = digits.length() - 1; + while (last_nonzero_idx > 0 + && digits.unicode()[last_nonzero_idx] == '0') + --last_nonzero_idx; + digits.truncate(last_nonzero_idx + 1); + } + + } + +#else + int mode; + if (form == DFDecimal) + mode = 3; + else + mode = 2; + + /* This next bit is a bit quirky. In DFExponent form, the precision + is the number of digits after decpt. So that would suggest using + mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and + precision=0. So we get around this by using mode=2 and reasoning + that we want precision+1 significant digits, since the decimal + point in this mode is always after the first digit. */ + int pr = precision; + if (form == DFExponent) + ++pr; + + char *rve = 0; + char *buff = 0; + digits = qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff); + if (buff != 0) + free(buff); +#endif // QT_QLOCALE_USES_FCVT + + if (zero().unicode() != '0') { + for (uint i = 0; i < digits.length(); ++i) + digits.ref(i).unicode() += zero().unicode() - '0'; + } + + bool always_show_decpt = flags & Alternate; + switch (form) { + case DFExponent: { + num_str = exponentForm(digits, decpt, precision, PMDecimalDigits, + always_show_decpt, *this); + break; + } + case DFDecimal: { + num_str = decimalForm(digits, decpt, precision, PMDecimalDigits, + always_show_decpt, flags & ThousandsGroup, + *this); + break; + } + case DFSignificantDigits: { + PrecisionMode mode = (flags & Alternate) ? + PMSignificantDigits : PMChopTrailingZeros; + + if (decpt != (int)digits.length() && (decpt <= -4 || decpt > (int)precision)) + num_str = exponentForm(digits, decpt, precision, mode, + always_show_decpt, *this); + else + num_str = decimalForm(digits, decpt, precision, mode, + always_show_decpt, flags & ThousandsGroup, + *this); + break; + } + } + + negative = sign != 0 && !isZero(d); + } + + // pad with zeros. LeftAdjusted overrides this flag). Also, we don't + // pad special numbers + if (flags & TQLocalePrivate::ZeroPadded + && !(flags & TQLocalePrivate::LeftAdjusted) + && !special_number) { + int num_pad_chars = width - (int)num_str.length(); + // leave space for the sign + if (negative + || flags & TQLocalePrivate::AlwaysShowSign + || flags & TQLocalePrivate::BlankBeforePositive) + --num_pad_chars; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(zero()); + } + + // add sign + if (negative) + num_str.prepend(minus()); + else if (flags & TQLocalePrivate::AlwaysShowSign) + num_str.prepend(plus()); + else if (flags & TQLocalePrivate::BlankBeforePositive) + num_str.prepend(' '); + + if (flags & TQLocalePrivate::CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +TQString TQLocalePrivate::longLongToString(TQ_LLONG l, int precision, + int base, int width, + unsigned flags) const +{ + bool precision_not_specified = FALSE; + if (precision == -1) { + precision_not_specified = TRUE; + precision = 1; + } + + bool negative = l < 0; + if (base != 10) { + // these are not suported by sprintf for octal and hex + flags &= ~AlwaysShowSign; + flags &= ~BlankBeforePositive; + negative = FALSE; // neither are negative numbers + } + + TQString num_str; + if (base == 10) + num_str = qlltoa(l, base, *this); + else + num_str = qulltoa(l, base, *this); + + uint cnt_thousand_sep = 0; + if (flags & ThousandsGroup && base == 10) { + for (int i = (int)num_str.length() - 3; i > 0; i -= 3) { + num_str.insert(i, group()); + ++cnt_thousand_sep; + } + } + + for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + + if (flags & Alternate + && base == 8 + && (num_str.isEmpty() + || num_str[0].unicode() != '0')) + num_str.prepend('0'); + + // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds + // when precision is not specified in the format string + bool zero_padded = flags & ZeroPadded + && !(flags & LeftAdjusted) + && precision_not_specified; + + if (zero_padded) { + int num_pad_chars = width - (int)num_str.length(); + + // leave space for the sign + if (negative + || flags & AlwaysShowSign + || flags & BlankBeforePositive) + --num_pad_chars; + + // leave space for optional '0x' in hex form + if (base == 16 + && flags & Alternate + && l != 0) + num_pad_chars -= 2; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + } + + if (base == 16 + && flags & Alternate + && l != 0) + num_str.prepend("0x"); + + // add sign + if (negative) + num_str.prepend(minus()); + else if (flags & AlwaysShowSign) + num_str.prepend(base == 10 ? plus() : TQChar('+')); + else if (flags & BlankBeforePositive) + num_str.prepend(' '); + + if (flags & CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +TQString TQLocalePrivate::unsLongLongToString(TQ_ULLONG l, int precision, + int base, int width, + unsigned flags) const +{ + bool precision_not_specified = FALSE; + if (precision == -1) { + precision_not_specified = TRUE; + precision = 1; + } + + TQString num_str = qulltoa(l, base, *this); + + uint cnt_thousand_sep = 0; + if (flags & ThousandsGroup && base == 10) { + for (int i = (int)num_str.length() - 3; i > 0; i -=3) { + num_str.insert(i, group()); + ++cnt_thousand_sep; + } + } + + for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + + if (flags & Alternate + && base == 8 + && (num_str.isEmpty() + || num_str[0].unicode() != '0')) + num_str.prepend('0'); + + // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds + // when precision is not specified in the format string + bool zero_padded = flags & ZeroPadded + && !(flags & LeftAdjusted) + && precision_not_specified; + + if (zero_padded) { + int num_pad_chars = width - (int)num_str.length(); + + // leave space for optional '0x' in hex form + if (base == 16 + && flags & Alternate + && l != 0) + num_pad_chars -= 2; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + } + + if (base == 16 + && flags & Alternate + && l != 0) + num_str.prepend("0x"); + + if (flags & CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +static inline bool isLatin1Digit(const TQChar &c) +{ + return c.unicode() >= '0' && c.unicode() <= '9'; +} + +// Removes thousand-group separators, ie. the ',' in "1,234,567.89e-5" +bool TQLocalePrivate::removeGroupSeparators(TQString &num_str) const +{ + int group_cnt = 0; // counts number of group chars + int decpt_idx = -1; + + // Find the decimal point and check if there are any group chars + uint i = 0; + for (; i < num_str.length(); ++i) { + TQChar c = num_str.unicode()[i]; + + if (c.unicode() == ',') { + // check that there are digits before and after the separator + if (i == 0 || !isLatin1Digit(num_str.unicode()[i - 1])) + return FALSE; + if (i == num_str.length() + 1 || !isLatin1Digit(num_str.unicode()[i + 1])) + return FALSE; + ++group_cnt; + } + else if (c.unicode() == '.') { + // Fail if more than one decimal points + if (decpt_idx != -1) + return FALSE; + decpt_idx = i; + } else if (c.unicode() == 'e' || c.unicode() == 'E') { + // an 'e' or 'E' - if we have not encountered a decimal + // point, this is where it "is". + if (decpt_idx == -1) + decpt_idx = i; + } + } + + // If no group chars, we're done + if (group_cnt == 0) + return TRUE; + + // No decimal point means that it "is" at the end of the string + if (decpt_idx == -1) + decpt_idx = num_str.length(); + + i = 0; + while (i < num_str.length() && group_cnt > 0) { + TQChar c = num_str.unicode()[i]; + + if (c.unicode() == ',') { + // Don't allow group chars after the decimal point + if ((int)i > decpt_idx) + return FALSE; + + // Check that it is placed correctly relative to the decpt + if ((decpt_idx - i) % 4 != 0) + return FALSE; + + // Remove it + num_str.remove(i, 1); + + --group_cnt; + --decpt_idx; // adjust decpt_idx + } else { + // Check that we are not missing a separator + if ((int)i < decpt_idx && (decpt_idx - i) % 4 == 0) + return FALSE; + ++i; + } + } + + return TRUE; +} + +static void stripWhiteSpaceInPlace(TQString &s) +{ + uint i = 0; + while (i < s.length() && s.unicode()[i].isSpace()) + ++i; + if (i > 0) + s.remove(0, i); + + i = s.length(); + + if (i == 0) + return; + --i; + while (i > 0 && s.unicode()[i].isSpace()) + --i; + if (i + 1 < s.length()) + s.truncate(i + 1); +} + +/* + Converts a number in locale to its representation in the C locale. + Only has to guarantee that a string that is a correct representation of + a number will be converted. If junk is passed in, junk will be passed + out and the error will be detected during the actual conversion to a + number. We can't detect junk here, since we don't even know the base + of the number. +*/ +bool TQLocalePrivate::numberToCLocale(TQString &l_num, + GroupSeparatorMode group_sep_mode) const +{ + stripWhiteSpaceInPlace(l_num); + + if (l_num.isEmpty()) + return FALSE; + + for (uint idx = 0; idx < l_num.length(); ++idx) { + TQChar &c = l_num.ref(idx); + + if (isDigit(c)) + c = digitToCLocale(zero(), c); + else if (c == plus()) + c = '+'; + else if (c == minus()) + c = '-'; + else if (c == decimal()) + c = '.'; + else if (c == group()) + c = ','; + // In several languages group() is the char 0xA0, which looks like a space. + // People use a regular space instead of it and complain it doesn't work. + else if (group().unicode() == 0xA0 && c.unicode() == ' ') + c = ','; + else if (c == exponential() || c == exponential().upper()) + c = 'e'; + else if (c == list()) + c = ';'; + else if (c == percent()) + c = '%'; + else if (c.unicode() >= 'A' && c.unicode() <= 'Z') + c = c.lower(); + else if (c.unicode() >= 'a' && c.unicode() <= 'z') + ; // do nothing + else + return FALSE; + } + + if (group_sep_mode == ParseGroupSeparators + && !removeGroupSeparators(l_num)) + return FALSE; + + return TRUE; +} + +double TQLocalePrivate::stringToDouble(TQString num, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + + if (ok != 0) + *ok = TRUE; + + if (num == "nan") + return NAN; + + if (num == "+inf" + || num == "inf") + return INFINITY; + + if (num == "-inf") + return -INFINITY; + + bool _ok; + const char *num_buff = num.latin1(); + +#ifdef QT_QLOCALE_USES_FCVT + char *endptr; + double d = strtod(num_buff, &endptr); + _ok = TRUE; +#else + const char *endptr; + double d = qstrtod(num_buff, &endptr, &_ok); +#endif + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + else + return d; +} + +TQ_LLONG TQLocalePrivate::stringToLongLong(TQString num, int base, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = FALSE; + return 0; + } + + bool _ok; + const char *endptr; + const char *num_buff = num.latin1(); + TQ_LLONG l = qstrtoll(num_buff, &endptr, base, &_ok); + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = FALSE; + return 0; + } + + if (ok != 0) + *ok = TRUE; + return l; +} + +TQ_ULLONG TQLocalePrivate::stringToUnsLongLong(TQString num, int base, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = FALSE; + return 0; + } + + bool _ok; + const char *endptr; + const char *num_buff = num.latin1(); + TQ_ULLONG l = qstrtoull(num_buff, &endptr, base, &_ok); + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = FALSE; + return 0; + } + + if (ok != 0) + *ok = TRUE; + return l; +} + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; +// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; + +/* + * Convert a string to an TQ_ULLONG integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok) +{ + const char *s = nptr; + TQ_ULLONG acc; + unsigned char c; + TQ_ULLONG qbase, cutoff; + int neg, any, cutlim; + + if (ok != 0) + *ok = TRUE; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + if (ok != 0) + *ok = FALSE; + if (endptr != 0) + *endptr = s - 1; + return 0; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + qbase = (unsigned)base; + cutoff = (TQ_ULLONG)ULLONG_MAX / qbase; + cutlim = (TQ_ULLONG)ULLONG_MAX % qbase; + for (acc = 0, any = 0;; c = *s++) { + if (!isascii(c)) + break; + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + if (ok != 0) + *ok = FALSE; + } + else if (neg) + acc = (~acc) + 1; + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + + +// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; + + +/* + * Convert a string to a TQ_LLONG integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok) +{ + const char *s; + TQ_ULLONG acc; + unsigned char c; + TQ_ULLONG qbase, cutoff; + int neg, any, cutlim; + + if (ok != 0) + *ok = TRUE; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + qbase = (unsigned)base; + cutoff = neg ? (TQ_ULLONG)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % qbase; + cutoff /= qbase; + for (acc = 0, any = 0;; c = *s++) { + if (!isascii(c)) + break; + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + if (ok != 0) + *ok = FALSE; + } else if (neg) { + acc = (~acc) + 1; + } + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +#ifndef QT_QLOCALE_USES_FCVT + +/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */ +/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */ + +/* Please send bug reports to + David M. Gay + AT&T Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-2070 + U.S.A. + dmg@research.att.com or research!dmg + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic. + * #define Unsigned_Shifts if >> does treats its left operand as unsigned. + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision + * integer arithmetic. Whether this speeds things up or slows things + * down depends on the machine and the number being converted. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +/* +#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ + defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ + defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MACX) || \ + defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS) +# define IEEE_BIG_OR_LITTLE_ENDIAN 1 +#endif +*/ + +// *All* of our architectures have IEEE arithmetic, don't they? +#define IEEE_BIG_OR_LITTLE_ENDIAN 1 + +#ifdef __arm32__ +/* + * Although the CPU is little endian the FP has different + * byte and word endianness. The byte order is still little endian + * but the word order is big endian. + */ +#define IEEE_BIG_OR_LITTLE_ENDIAN +#endif + +#ifdef vax +#define VAX +#endif + +#define Long TQ_INT32 +#define ULong TQ_UINT32 + +#define MALLOC malloc +#define CONST const + +#ifdef BSD_QDTOA_DEBUG +#include +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#ifdef Unsigned_Shifts +#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; +#else +#define Sign_Extend(a,b) /*no-op*/ +#endif + +#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1 +#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined. +#endif + +inline ULong getWord0(const NEEDS_VOLATILE double x) +{ + const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); + if (ByteOrder == BigEndian) { + return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; + } else { + return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4]; + } +} + +inline void setWord0(NEEDS_VOLATILE double *x, ULong l) +{ + NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); + if (ByteOrder == BigEndian) { + ptr[0] = (uchar)(l>>24); + ptr[1] = (uchar)(l>>16); + ptr[2] = (uchar)(l>>8); + ptr[3] = (uchar)l; + } else { + ptr[7] = (uchar)(l>>24); + ptr[6] = (uchar)(l>>16); + ptr[5] = (uchar)(l>>8); + ptr[4] = (uchar)l; + } +} + +inline ULong getWord1(const NEEDS_VOLATILE double x) +{ + const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); + if (ByteOrder == BigEndian) { + return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7]; + } else { + return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0]; + } +} +inline void setWord1(NEEDS_VOLATILE double *x, ULong l) +{ + NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); + if (ByteOrder == BigEndian) { + ptr[4] = (uchar)(l>>24); + ptr[5] = (uchar)(l>>16); + ptr[6] = (uchar)(l>>8); + ptr[7] = (uchar)l; + } else { + ptr[3] = (uchar)(l>>24); + ptr[2] = (uchar)(l>>16); + ptr[1] = (uchar)(l>>8); + ptr[0] = (uchar)l; + } +} + +static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c) +{ + + *a = (((unsigned short)b) << 16) | ((unsigned short)c); + ++a; +} + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#if defined(IEEE_BIG_OR_LITTLE_ENDIAN) +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define IEEE_Arith +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */ +#else +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif +#endif + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +extern double rnd_prod(double, double), rnd_quot(double, double); +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Just_16 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#ifndef Pack_32 +#define Pack_32 +#endif +#endif + +#define Kmax 15 + +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + + typedef struct Bigint Bigint; + +static Bigint *Balloc(int k) +{ + int x; + Bigint *rv; + + x = 1 << k; + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); + rv->k = k; + rv->maxwds = x; + rv->sign = rv->wds = 0; + return rv; +} + +static void Bfree(Bigint *v) +{ + free(v); +} + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ +y->wds*sizeof(Long) + 2*sizeof(int)) + +/* multiply by m and add a */ +static Bigint *multadd(Bigint *b, int m, int a) +{ + int i, wds; + ULong *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + do { +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + a; + z = (xi >> 16) * m + (y >> 16); + a = (int)(z >> 16); + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + a; + a = (int)(y >> 16); + *x++ = y & 0xffff; +#endif + } + while(++i < wds); + if (a) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = a; + b->wds = wds; + } + return b; +} + +static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; +} + +static int hi0bits(ULong x) +{ + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +static int lo0bits(ULong *y) +{ + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x & 1) + return 32; + } + *y = x; + return k; +} + +static Bigint *i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} + +static Bigint *mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong carry, y, z; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; +#ifdef Pack_32 + ULong z2; +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if ((y = *xb & 0xffff) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ((y = *xb >> 16) != 0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint *pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3) != 0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { + /* first time */ + p5 = p5s = i2b(625); + p5->next = 0; + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + p5 = p51; + } + return b; +} + +static Bigint *lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) != 0) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; + } +#endif + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef BSD_QDTOA_DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +static Bigint *diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + Long borrow, y; /* We need signed shifts here. */ + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef Pack_32 + Long z; +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; +} + +static double ulp(double x) +{ + Long L; + double a; + + L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + setWord0(&a, L); + setWord1(&a, 0); +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + setWord0(&a, 0x80000 >> L); + setWord1(&a, 0); + } + else { + setWord0(&a, 0); + L -= Exp_shift; + setWord1(&a, L >= 31 ? 1U : 1U << (31 - L)); + } + } +#endif + return a; +} + +static double b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + double d; + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef BSD_QDTOA_DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + setWord0(&d, Exp_1 | y >> (Ebits - k)); + w = xa > xa0 ? *--xa : 0; + setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k)); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + setWord0(&d, Exp_1 | y << k | z >> (32 - k)); + y = xa > xa0 ? *--xa : 0; + setWord1(&d, z << k | y >> (32 - k)); + } + else { + setWord0(&d, Exp_1 | y); + setWord1(&d, z); + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k); + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k); + y = xa > xa0 ? *--xa : 0; + setWord1(&d, w << k + 16 | y << k); +#endif + ret_d: + return d; +} + +static Bigint *d2b(double d, int *e, int *bits) +{ + Bigint *b; + int de, i, k; + ULong *x, y, z; + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = getWord0(d) & Frac_mask; + setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(getWord0(d) >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(getWord0(d) >> Exp_shift)) != 0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = getWord1(d)) != 0) { + if ((k = lo0bits(&y)) != 0) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = b->wds = (x[1] = z) ? 2 : 1; + } + else { +#ifdef BSD_QDTOA_DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; + i = b->wds = 1; + k += 32; + } +#else + if (y = getWord1(d)) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef BSD_QDTOA_DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; +} + +static double ratio(Bigint *a, Bigint *b) +{ + double da, db; + int k, ka, kb; + + da = b2d(a, &ka); + db = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1); + if (k &= 3) + da *= 1 << k; + } + else { + k = -k; + setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1); + if (k &= 3) + db *= 1 << k; + } +#else + if (k > 0) + setWord0(&da, getWord0(da) + k*Exp_msk1); + else { + k = -k; + setWord0(&db, getWord0(db) + k*Exp_msk1); + } +#endif + return da / db; +} + +static CONST double tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif +}; + +#ifdef IEEE_Arith +static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; +#define n_bigtens 5 +#else +#ifdef IBM +static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +static CONST double bigtens[] = { 1e16, 1e32 }; +static CONST double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +/* + The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes + the comparison 1e-100 == 0.0 to return true. As a workaround, we + compare it to a global variable containing 0.0, which produces + correct assembler output. + + ### consider detecting the broken compilers and using the static + ### double for these, and use a #define for all working compilers +*/ +static double g_double_zero = 0.0; + +static double qstrtod(CONST char *s00, CONST char **se, bool *ok) +{ + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj, rv, rv0; + Long L; + ULong y, z; + Bigint *bb1, *bd0; + Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */ + + /* + #ifndef KR_headers + CONST char decimal_point = localeconv()->decimal_point[0]; + #else + CONST char decimal_point = '.'; + #endif */ + if (ok != 0) + *ok = TRUE; + + CONST char decimal_point = '.'; + + sign = nz0 = nz = 0; + rv = 0.; + + + for(s = s00; isspace((unsigned char) *s); s++) + ; + + if (*s == '-') { + sign = 1; + s++; + } else if (*s == '+') { + s++; + } + + if (*s == '\0') { + s = s00; + goto ret; + } + + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + if (c == decimal_point) { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) + s = s00; + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + rv = y; + if (k > 9) + rv = tens[k - 9] * rv + z; + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT + && FLT_ROUNDS == 1 +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else + /* rv = */ rounded_product(rv, tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + rv *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + /* rv = */ rounded_product(rv, tens[e]); + if ((getWord0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + setWord0(&rv, getWord0(rv) + P*Exp_msk1); +#else + /* rv = */ rounded_product(rv, tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { + /* rv = */ rounded_quotient(rv, tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15) != 0) + rv *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + // errno = ERANGE; + if (ok != 0) + *ok = FALSE; +#ifdef __STDC__ + rv = HUGE_VAL; +#else + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith + setWord0(&rv, Exp_mask); + setWord1(&rv, 0); +#else + setWord0(&rv, Big0); + setWord1(&rv, Big1); +#endif +#endif + if (bd0) + goto retfree; + goto ret; + } + if (e1 >>= 4) { + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= bigtens[j]; + /* The last multiplication could overflow. */ + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + rv *= bigtens[j]; + if ((z = getWord0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + setWord0(&rv, Big0); + setWord1(&rv, Big1); + } + else + setWord0(&rv, getWord0(rv) + P*Exp_msk1); + } + + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15) != 0) + rv /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + if (e1 >= 1 << n_bigtens) + goto undfl; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= tinytens[j]; + /* The last multiplication could underflow. */ + rv0 = rv; + rv *= tinytens[j]; + if (rv == g_double_zero) + { + rv = 2.*rv0; + rv *= tinytens[j]; + if (rv == g_double_zero) + { + undfl: + rv = 0.; + // errno = ERANGE; + if (ok != 0) + *ok = FALSE; + if (bd0) + goto retfree; + goto ret; + } + setWord0(&rv, Tiny0); + setWord1(&rv, Tiny1); + /* The refinement below will clean + * this approximation up. + */ + } + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else + i = bbe + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j = bbe + (P-Emin); + else + j = P + 1 - bbbits; +#endif + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) + break; + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1 + && getWord1(rv) == 0xffffffff) { + /*boundary case -- increment exponent*/ + setWord0(&rv, (getWord0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ); + setWord1(&rv, 0); + break; + } + } + else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow + L = getWord0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else + if (L <= Exp_msk1) +#endif + goto undfl; + L -= Exp_msk1; +#else + L = (getWord0(rv) & Exp_mask) - Exp_msk1; +#endif + setWord0(&rv, L | Bndry_mask1); + setWord1(&rv, 0xffffffff); +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(getWord1(rv) & LSB)) + break; +#endif + if (dsign) + rv += ulp(rv); +#ifndef ROUND_BIASED + else { + rv -= ulp(rv); +#ifndef Sudden_Underflow + if (rv == g_double_zero) + goto undfl; +#endif + } +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (getWord1(rv) || getWord0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (getWord1(rv) == Tiny1 && !getWord0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(FLT_ROUNDS) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (FLT_ROUNDS == 0) + aadj1 += 0.5; +#endif + } + y = getWord0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + rv0 = rv; + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + adj = aadj1 * ulp(rv); + rv += adj; + if ((getWord0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1) + goto ovfl; + setWord0(&rv, Big0); + setWord1(&rv, Big1); + goto cont; + } + else + setWord0(&rv, getWord0(rv) + P*Exp_msk1); + } + else { +#ifdef Sudden_Underflow + if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) { + rv0 = rv; + setWord0(&rv, getWord0(rv) + P*Exp_msk1); + adj = aadj1 * ulp(rv); + rv += adj; +#ifdef IBM + if ((getWord0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (getWord0(rv0) == Tiny0 + && getWord1(rv0) == Tiny1) + goto undfl; + setWord0(&rv, Tiny0); + setWord1(&rv, Tiny1); + goto cont; + } + else + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + } + else { + adj = aadj1 * ulp(rv); + rv += adj; + } +#else + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(rv); + rv += adj; +#endif + } + z = getWord0(rv) & Exp_mask; + if (y == z) { + /* Can we stop now? */ + L = (Long) aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -rv : rv; +} + +static int quorem(Bigint *b, Bigint *S) +{ + int n; + Long borrow, y; + ULong carry, q, ys; + ULong *bx, *bxe, *sx, *sxe; +#ifdef Pack_32 + Long z; + ULong si, zs; +#endif + + n = S->wds; +#ifdef BSD_QDTOA_DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef BSD_QDTOA_DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + +/* This actually sometimes returns a pointer to a string literal + cast to a char*. Do NOT try to modify the return value. */ + +static char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) +{ + // Some values of the floating-point control word can cause _qdtoa to crash with an underflow. + // We set a safe value here. +#ifdef Q_OS_WIN +#ifndef Q_CC_BOR + unsigned int oldbits = _control87(0, 0); +#ifndef _M_X64 //x64 does not support precition control + _control87(0x9001F, 0xFFFFF); +#else + _control87(0x9001F, _MCW_DN|_MCW_EM|_MCW_RC); +#endif //_M_X64 +#endif +#endif + +#ifdef Q_OS_LINUX + fenv_t envp; + feholdexcept(&envp); +#endif + + char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp); + +#ifdef Q_OS_WIN +#ifndef Q_CC_BOR + _clear87(); +#ifndef _M_X64 + _control87(oldbits, 0xFFFFF); +#else + _control87(oldbits, _MCW_DN|_MCW_EM|_MCW_RC); +#endif //_M_X64 +#endif +#endif + +#ifdef Q_OS_LINUX + fesetenv(&envp); +#endif + + return s; +} + +static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) +{ + /* + Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim0, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + try_quick; + int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */ + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mhi, *S; + Bigint *mlo = NULL; /* pacify gcc */ + double d2; + double ds, eps; + char *s, *s0; + + if (getWord0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((getWord0(d) & Exp_mask) == Exp_mask) +#else + if (getWord0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; + s = +#ifdef IEEE_Arith + !getWord1(d) && !(getWord0(d) & 0xfffff) ? (char*)"Infinity" : +#endif + (char*)"NaN"; + if (rve) + *rve = +#ifdef IEEE_Arith + s[3] ? s + 8 : +#endif + s + 3; + return s; + } +#endif +#ifdef IBM + d += 0; /* normalize */ +#endif + if (d == g_double_zero) + { + *decpt = 1; + s = (char*) "0"; + if (rve) + *rve = s + 1; + return s; + } + + b = d2b(d, &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { +#endif + d2 = d; + setWord0(&d2, getWord0(d2) & Frac_mask1); + setWord0(&d2, getWord0(d2) | Exp_11); +#ifdef IBM + if (j = 11 - hi0bits(getWord0(d2) & Frac_mask)) + d2 /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32) + : getWord1(d) << (32 - i); + d2 = x; + setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (d < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + *resultp = (char *) malloc(i + 1); + s = s0 = *resultp; + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = d; + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + d /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + d /= ds; + } + else if ((j1 = -k) != 0) { + d *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + d *= bigtens[i]; + } + } + if (k_check && d < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + d *= 10.; + ieps++; + } + eps = ieps*d + 7.; + setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1); + if (ilim == 0) { + S = mhi = 0; + d -= 5.; + if (d > eps) + goto one_digit; + if (d < -eps) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + eps = 0.5/tens[ilim-1] - eps; + for(i = 0;;) { + L = (Long)d; + d -= L; + *s++ = '0' + (int)L; + if (d < eps) + goto ret1; + if (1. - d < eps) + goto bump_up; + if (++i >= ilim) + break; + eps *= 10.; + d *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + eps *= tens[ilim-1]; + for(i = 1;; i++, d *= 10.) { + L = (Long)d; + d -= L; + *s++ = '0' + (int)L; + if (i == ilim) { + if (d > 0.5 + eps) + goto bump_up; + else if (d < 0.5 - eps) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + d = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || d <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++) { + L = (Long)(d / ds); + d -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (d < 0) { + L--; + d += ds; + } +#endif + *s++ = '0' + (int)L; + if (i == ilim) { + d += d; + if (d > ds || (d == ds && L & 1)) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + if ((d *= 10.) == g_double_zero) + break; + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + if (mode < 2) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5) != 0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + if (mode < 2) { + if (!getWord1(d) && !(getWord0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && getWord0(d) & Exp_mask +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + else + spec_case = 0; + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) + i = 32 - i; +#else + if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(getWord1(d) & 1)) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && !mode +#ifndef ROUND_BIASED + && !(getWord1(d) & 1) +#endif + )) { + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && dig & 1)) + && dig++ == '9') + goto round_9_up; + } + *s++ = dig; + goto ret; + } + if (j1 > 0) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || (j == 0 && dig & 1)) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + if (s == s0) { /* don't return empty string */ + *s++ = '0'; + k = 0; + } + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; +} + +#endif // QT_QLOCALE_USES_FCVT diff --git a/src/tools/tqlocale.h b/src/tools/tqlocale.h new file mode 100644 index 000000000..d3a578d1c --- /dev/null +++ b/src/tools/tqlocale.h @@ -0,0 +1,494 @@ +/**************************************************************************** +** +** Declaration of the TQLocale class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the tools module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQLOCALE_H +#define TQLOCALE_H + +#include "tqstring.h" + +struct TQLocalePrivate; + +class TQ_EXPORT TQLocale +{ + friend class TQString; + +public: + enum Language { + C = 1, + Abkhazian = 2, + Afan = 3, + Afar = 4, + Afrikaans = 5, + Albanian = 6, + Amharic = 7, + Arabic = 8, + Armenian = 9, + Assamese = 10, + Aymara = 11, + Azerbaijani = 12, + Bashkir = 13, + Basque = 14, + Bengali = 15, + Bhutani = 16, + Bihari = 17, + Bislama = 18, + Breton = 19, + Bulgarian = 20, + Burmese = 21, + Byelorussian = 22, + Cambodian = 23, + Catalan = 24, + Chinese = 25, + Corsican = 26, + Croatian = 27, + Czech = 28, + Danish = 29, + Dutch = 30, + English = 31, + Esperanto = 32, + Estonian = 33, + Faroese = 34, + FijiLanguage = 35, + Finnish = 36, + French = 37, + Frisian = 38, + Gaelic = 39, + Galician = 40, + Georgian = 41, + German = 42, + Greek = 43, + Greenlandic = 44, + Guarani = 45, + Gujarati = 46, + Hausa = 47, + Hebrew = 48, + Hindi = 49, + Hungarian = 50, + Icelandic = 51, + Indonesian = 52, + Interlingua = 53, + Interlingue = 54, + Inuktitut = 55, + Inupiak = 56, + Irish = 57, + Italian = 58, + Japanese = 59, + Javanese = 60, + Kannada = 61, + Kashmiri = 62, + Kazakh = 63, + Kinyarwanda = 64, + Kirghiz = 65, + Korean = 66, + Kurdish = 67, + Kurundi = 68, + Laothian = 69, + Latin = 70, + Latvian = 71, + Lingala = 72, + Lithuanian = 73, + Macedonian = 74, + Malagasy = 75, + Malay = 76, + Malayalam = 77, + Maltese = 78, + Maori = 79, + Marathi = 80, + Moldavian = 81, + Mongolian = 82, + NauruLanguage = 83, + Nepali = 84, + Norwegian = 85, + Occitan = 86, + Oriya = 87, + Pashto = 88, + Persian = 89, + Polish = 90, + Portuguese = 91, + Punjabi = 92, + Quechua = 93, + RhaetoRomance = 94, + Romanian = 95, + Russian = 96, + Samoan = 97, + Sangho = 98, + Sanskrit = 99, + Serbian = 100, + SerboCroatian = 101, + Sesotho = 102, + Setswana = 103, + Shona = 104, + Sindhi = 105, + Singhalese = 106, + Siswati = 107, + Slovak = 108, + Slovenian = 109, + Somali = 110, + Spanish = 111, + Sundanese = 112, + Swahili = 113, + Swedish = 114, + Tagalog = 115, + Tajik = 116, + Tamil = 117, + Tatar = 118, + Telugu = 119, + Thai = 120, + Tibetan = 121, + Tigrinya = 122, + TongaLanguage = 123, + Tsonga = 124, + Turkish = 125, + Turkmen = 126, + Twi = 127, + Uigur = 128, + Ukrainian = 129, + Urdu = 130, + Uzbek = 131, + Vietnamese = 132, + Volapuk = 133, + Welsh = 134, + Wolof = 135, + Xhosa = 136, + Yiddish = 137, + Yoruba = 138, + Zhuang = 139, + Zulu = 140, + LastLanguage = Zulu + }; + + enum Country { + AnyCountry = 0, + Afghanistan = 1, + Albania = 2, + Algeria = 3, + AmericanSamoa = 4, + Andorra = 5, + Angola = 6, + Anguilla = 7, + Antarctica = 8, + AntiguaAndBarbuda = 9, + Argentina = 10, + Armenia = 11, + Aruba = 12, + Australia = 13, + Austria = 14, + Azerbaijan = 15, + Bahamas = 16, + Bahrain = 17, + Bangladesh = 18, + Barbados = 19, + Belarus = 20, + Belgium = 21, + Belize = 22, + Benin = 23, + Bermuda = 24, + Bhutan = 25, + Bolivia = 26, + BosniaAndHerzegowina = 27, + Botswana = 28, + BouvetIsland = 29, + Brazil = 30, + BritishIndianOceanTerritory = 31, + BruneiDarussalam = 32, + Bulgaria = 33, + BurkinaFaso = 34, + Burundi = 35, + Cambodia = 36, + Cameroon = 37, + Canada = 38, + CapeVerde = 39, + CaymanIslands = 40, + CentralAfricanRepublic = 41, + Chad = 42, + Chile = 43, + China = 44, + ChristmasIsland = 45, + CocosIslands = 46, + Colombia = 47, + Comoros = 48, + DemocraticRepublicOfCongo = 49, + PeoplesRepublicOfCongo = 50, + CookIslands = 51, + CostaRica = 52, + IvoryCoast = 53, + Croatia = 54, + Cuba = 55, + Cyprus = 56, + CzechRepublic = 57, + Denmark = 58, + Djibouti = 59, + Dominica = 60, + DominicanRepublic = 61, + EastTimor = 62, + Ecuador = 63, + Egypt = 64, + ElSalvador = 65, + EquatorialGuinea = 66, + Eritrea = 67, + Estonia = 68, + Ethiopia = 69, + FalklandIslands = 70, + FaroeIslands = 71, + FijiCountry = 72, + Finland = 73, + France = 74, + MetropolitanFrance = 75, + FrenchGuiana = 76, + FrenchPolynesia = 77, + FrenchSouthernTerritories = 78, + Gabon = 79, + Gambia = 80, + Georgia = 81, + Germany = 82, + Ghana = 83, + Gibraltar = 84, + Greece = 85, + Greenland = 86, + Grenada = 87, + Guadeloupe = 88, + Guam = 89, + Guatemala = 90, + Guinea = 91, + GuineaBissau = 92, + Guyana = 93, + Haiti = 94, + HeardAndMcDonaldIslands = 95, + Honduras = 96, + HongKong = 97, + Hungary = 98, + Iceland = 99, + India = 100, + Indonesia = 101, + Iran = 102, + Iraq = 103, + Ireland = 104, + Israel = 105, + Italy = 106, + Jamaica = 107, + Japan = 108, + Jordan = 109, + Kazakhstan = 110, + Kenya = 111, + Kiribati = 112, + DemocraticRepublicOfKorea = 113, + RepublicOfKorea = 114, + Kuwait = 115, + Kyrgyzstan = 116, + Lao = 117, + Latvia = 118, + Lebanon = 119, + Lesotho = 120, + Liberia = 121, + LibyanArabJamahiriya = 122, + Liechtenstein = 123, + Lithuania = 124, + Luxembourg = 125, + Macau = 126, + Macedonia = 127, + Madagascar = 128, + Malawi = 129, + Malaysia = 130, + Maldives = 131, + Mali = 132, + Malta = 133, + MarshallIslands = 134, + Martinique = 135, + Mauritania = 136, + Mauritius = 137, + Mayotte = 138, + Mexico = 139, + Micronesia = 140, + Moldova = 141, + Monaco = 142, + Mongolia = 143, + Montserrat = 144, + Morocco = 145, + Mozambique = 146, + Myanmar = 147, + Namibia = 148, + NauruCountry = 149, + Nepal = 150, + Netherlands = 151, + NetherlandsAntilles = 152, + NewCaledonia = 153, + NewZealand = 154, + Nicaragua = 155, + Niger = 156, + Nigeria = 157, + Niue = 158, + NorfolkIsland = 159, + NorthernMarianaIslands = 160, + Norway = 161, + Oman = 162, + Pakistan = 163, + Palau = 164, + PalestinianTerritory = 165, + Panama = 166, + PapuaNewGuinea = 167, + Paraguay = 168, + Peru = 169, + Philippines = 170, + Pitcairn = 171, + Poland = 172, + Portugal = 173, + PuertoRico = 174, + Qatar = 175, + Reunion = 176, + Romania = 177, + RussianFederation = 178, + Rwanda = 179, + SaintKittsAndNevis = 180, + StLucia = 181, + StVincentAndTheGrenadines = 182, + Samoa = 183, + SanMarino = 184, + SaoTomeAndPrincipe = 185, + SaudiArabia = 186, + Senegal = 187, + Seychelles = 188, + SierraLeone = 189, + Singapore = 190, + Slovakia = 191, + Slovenia = 192, + SolomonIslands = 193, + Somalia = 194, + SouthAfrica = 195, + SouthGeorgiaAndTheSouthSandwichIslands = 196, + Spain = 197, + SriLanka = 198, + StHelena = 199, + StPierreAndMiquelon = 200, + Sudan = 201, + Suriname = 202, + SvalbardAndJanMayenIslands = 203, + Swaziland = 204, + Sweden = 205, + Switzerland = 206, + SyrianArabRepublic = 207, + Taiwan = 208, + Tajikistan = 209, + Tanzania = 210, + Thailand = 211, + Togo = 212, + Tokelau = 213, + TongaCountry = 214, + TrinidadAndTobago = 215, + Tunisia = 216, + Turkey = 217, + Turkmenistan = 218, + TurksAndCaicosIslands = 219, + Tuvalu = 220, + Uganda = 221, + Ukraine = 222, + UnitedArabEmirates = 223, + UnitedKingdom = 224, + UnitedStates = 225, + UnitedStatesMinorOutlyingIslands = 226, + Uruguay = 227, + Uzbekistan = 228, + Vanuatu = 229, + VaticanCityState = 230, + Venezuela = 231, + VietNam = 232, + BritishVirginIslands = 233, + USVirginIslands = 234, + WallisAndFutunaIslands = 235, + WesternSahara = 236, + Yemen = 237, + Yugoslavia = 238, + Zambia = 239, + Zimbabwe = 240, + LastCountry = Zimbabwe + }; + + TQLocale(); + TQLocale(const TQString &name); + TQLocale(Language language, Country country = AnyCountry); + TQLocale(const TQLocale &other); + + TQLocale &operator=(const TQLocale &other); + + Language language() const; + Country country() const; + TQString name() const; + + short toShort(const TQString &s, bool *ok = 0) const; + ushort toUShort(const TQString &s, bool *ok = 0) const; + int toInt(const TQString &s, bool *ok = 0) const; + uint toUInt(const TQString &s, bool *ok = 0) const; + TQ_LONG toLong(const TQString &s, bool *ok = 0) const; + TQ_ULONG toULong(const TQString &s, bool *ok = 0) const; + TQ_LLONG toLongLong(const TQString &s, bool *ok = 0) const; + TQ_ULLONG toULongLong(const TQString &s, bool *ok = 0) const; + float toFloat(const TQString &s, bool *ok = 0) const; + double toDouble(const TQString &s, bool *ok = 0) const; + + TQString toString(short i) const + { return toString((TQ_LLONG)i); } + TQString toString(ushort i) const + { return toString((TQ_ULLONG)i); } + TQString toString(int i) const + { return toString((TQ_LLONG)i); } + TQString toString(uint i) const + { return toString((TQ_ULLONG)i); } +#if !defined(Q_OS_WIN64) + TQString toString(TQ_LONG i) const + { return toString((TQ_LLONG)i); } + TQString toString(TQ_ULONG i) const + { return toString((TQ_ULLONG)i); } +#endif + TQString toString(TQ_LLONG i) const; + TQString toString(TQ_ULLONG i) const; + TQString toString(float i, char f = 'g', int prec = 6) const + { return toString((double) i, f, prec); } + TQString toString(double i, char f = 'g', int prec = 6) const; + + static TQString languageToString(Language language); + static TQString countryToString(Country country); + static void setDefault(const TQLocale &locale); + + static TQLocale c() { return TQLocale(C); } + static TQLocale system(); + +private: + const TQLocalePrivate *d; + static const TQLocalePrivate *default_d; +}; + +#endif diff --git a/src/tools/tqlocale_p.h b/src/tools/tqlocale_p.h new file mode 100644 index 000000000..8d562d22c --- /dev/null +++ b/src/tools/tqlocale_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Declaration of the TQLocalePrivate class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQLOCALE_P_H +#define TQLOCALE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the TQt API. It exists for the convenience +// of internal files. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// +// + +#include + +struct TQLocalePrivate +{ +public: + const TQChar &decimal() const { return (TQChar&)m_decimal; } + const TQChar &group() const { return (TQChar&)m_group; } + const TQChar &list() const { return (TQChar&)m_list; } + const TQChar &percent() const { return (TQChar&)m_percent; } + const TQChar &zero() const { return (TQChar&)m_zero; } + TQChar plus() const { return TQChar('+'); } + const TQChar &minus() const { return (TQChar&)m_minus; } + const TQChar &exponential() const { return (TQChar&)m_exponential; } + TQString infinity() const; + TQString nan() const; + + TQ_UINT32 languageId() const { return m_language_id; } + TQ_UINT32 countryId() const { return m_country_id; } + + bool isDigit(TQChar d) const; + + enum GroupSeparatorMode { + FailOnGroupSeparators, + ParseGroupSeparators + }; + + enum DoubleForm { + DFExponent = 0, // %e or %E + DFDecimal, // %f or %F + DFSignificantDigits, // %g or %G + _DFMax = DFSignificantDigits + }; + + enum Flags { + NoFlags = 0, + + // These correspond to the options in a printf format string + Alternate = 0x01, + ZeroPadded = 0x02, + LeftAdjusted = 0x04, + BlankBeforePositive = 0x08, + AlwaysShowSign = 0x10, + ThousandsGroup = 0x20, + CapitalEorX = 0x40 // %x, %e, %f, %g vs. %X, %E, %F, %G + }; + + TQString doubleToString(double d, + int precision = -1, + DoubleForm form = DFSignificantDigits, + int width = -1, + unsigned flags = NoFlags) const; + TQString longLongToString(TQ_LLONG l, int precision = -1, + int base = 10, + int width = -1, + unsigned flags = NoFlags) const; + TQString unsLongLongToString(TQ_ULLONG l, int precision = -1, + int base = 10, + int width = -1, + unsigned flags = NoFlags) const; + double stringToDouble(TQString num, bool *ok, GroupSeparatorMode group_sep_mode) const; + TQ_LLONG stringToLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; + TQ_ULLONG stringToUnsLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; + bool removeGroupSeparators(TQString &num_str) const; + bool numberToCLocale(TQString &locale_num, GroupSeparatorMode group_sep_mode) const; + + TQ_UINT32 m_language_id, m_country_id; + + TQ_UINT16 m_decimal, m_group, m_list, m_percent, + m_zero, m_minus, m_exponential; + + static const TQString m_infinity; + static const TQString m_nan; + static const TQChar m_plus; + + static const char *systemLocaleName(); +}; + +#endif diff --git a/src/tools/tqstring.cpp b/src/tools/tqstring.cpp index 58a377cd7..546069d48 100644 --- a/src/tools/tqstring.cpp +++ b/src/tools/tqstring.cpp @@ -56,8 +56,8 @@ #ifndef TQT_NO_TEXTCODEC #include "tqtextcodec.h" #endif -#include "ntqlocale.h" -#include "qlocale_p.h" +#include "tqlocale.h" +#include "tqlocale_p.h" #include "qunicodetables_p.h" #include -- cgit v1.2.3