diff options
Diffstat (limited to 'tqtinterface/qt4/src/tools/tqlocale.cpp')
-rw-r--r-- | tqtinterface/qt4/src/tools/tqlocale.cpp | 6322 |
1 files changed, 0 insertions, 6322 deletions
diff --git a/tqtinterface/qt4/src/tools/tqlocale.cpp b/tqtinterface/qt4/src/tools/tqlocale.cpp deleted file mode 100644 index e91cab8..0000000 --- a/tqtinterface/qt4/src/tools/tqlocale.cpp +++ /dev/null @@ -1,6322 +0,0 @@ -/**************************************************************************** -** -** Implementation of the TQLocale class -** -** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. -** -** 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 <sys/types.h> -#include <ctype.h> -#include <float.h> -#include <limits.h> -#include <math.h> -#include <stdlib.h> - -#include "tqlocale.h" -#include "tqlocale_p.h" -#include "tqnamespace.h" - -#ifdef TQT_TQLOCALE_USES_FCVT -# include <tqmutex.h> -# include <private/tqmutexpool_p.h> -#endif - -#if defined (TQ_OS_WIN) -# include <windows.h> -# undef NAN // we want to use our fallback on Windows -# undef INFINITY -#endif - -#ifdef TQ_OS_LINUX -# include <fenv.h> -#endif - -#if !defined( TQWS ) && defined( TQ_OS_MAC ) -# include <Carbon/Carbon.h> -#endif - -#if defined (TQ_OS_SOLARIS) -# include <ieeefp.h> -#endif - -#if defined (TQ_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) -# define INFINITY DBL_INFINITY -# define NAN DBL_TQNAN -#endif - -#if (defined(TQ_CC_GNU) && defined(TQ_OS_WIN)) || __GNUC__ == 4 || defined(TQT_TQLOCALE_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 TQT_TQLOCALE_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, register int base, bool *ok); -static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, register 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" -"DetqmocraticRepublicOfCongo\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" -"DetqmocraticRepublicOfKorea\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,// DetqmocraticRepublicOfCongo - 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,// DetqmocraticRepublicOfKorea - 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" // DetqmocraticRepublicOfCongo -"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" // DetqmocraticRepublicOfKorea -"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.tqunicode()[0].tqunicode(); - ushort uc2 = code.tqunicode()[1].tqunicode(); - - 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.tqunicode()[0].tqunicode(); - ushort uc2 = code.tqunicode()[1].tqunicode(); - - 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::tqfromLatin1("inf"); -} - -TQString TQLocalePrivate::nan() const -{ - return TQString::tqfromLatin1("nan"); -} - -#if defined(TQ_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 // TQ_OS_WIN - -const char* TQLocalePrivate::systemLocaleName() -{ - static TQCString lang; - lang = getenv( "LANG" ); - -#if !defined( TQWS ) && defined( TQ_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 { - TQT_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; - - TQ_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 DetqmocraticRepublicOfCongo - \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 DetqmocraticRepublicOfKorea - \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.tqunicode(); - 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 TQT_MAX_FLOAT 3.4028234663852886e+38 - -float TQLocale::toFloat(const TQString &s, bool *ok) const -{ - bool myOk; - double d = toDouble(s, &myOk); - if (!myOk || d > TQT_MAX_FLOAT || d < -TQT_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 TQ_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().tqunicode() <= d.tqunicode() - && zero().tqunicode() + 10 > d.tqunicode(); -} - -static char digitToCLocale(TQChar zero, TQChar d) -{ - if (zero.tqunicode() <= d.tqunicode() - && zero.tqunicode() + 10 > d.tqunicode()) - return '0' + d.tqunicode() - zero.tqunicode(); - - qWarning("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().tqunicode() == '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().tqunicode() + 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 TQ_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 TQT_TQLOCALE_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.tqunicode()[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 // TQT_TQLOCALE_USES_FCVT - - if (zero().tqunicode() != '0') { - for (uint i = 0; i < digits.length(); ++i) - digits.ref(i).unicode() += zero().tqunicode() - '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.tqunicode() >= '0' && c.tqunicode() <= '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.tqunicode()[i]; - - if (c.tqunicode() == ',') { - // check that there are digits before and after the separator - if (i == 0 || !isLatin1Digit(num_str.tqunicode()[i - 1])) - return FALSE; - if (i == num_str.length() + 1 || !isLatin1Digit(num_str.tqunicode()[i + 1])) - return FALSE; - ++group_cnt; - } - else if (c.tqunicode() == '.') { - // Fail if more than one decimal points - if (decpt_idx != -1) - return FALSE; - decpt_idx = i; - } else if (c.tqunicode() == 'e' || c.tqunicode() == '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.tqunicode()[i]; - - if (c.tqunicode() == ',') { - // 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.tqunicode()[i].isSpace()) - ++i; - if (i > 0) - s.remove(0, i); - - i = s.length(); - - if (i == 0) - return; - --i; - while (i > 0 && s.tqunicode()[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().tqunicode() == 0xA0 && c.tqunicode() == ' ') - c = ','; - else if (c == exponential() || c == exponential().upper()) - c = 'e'; - else if (c == list()) - c = ';'; - else if (c == percent()) - c = '%'; - else if (c.tqunicode() >= 'A' && c.tqunicode() <= 'Z') - c = c.lower(); - else if (c.tqunicode() >= 'a' && c.tqunicode() <= '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 TQT_TQLOCALE_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 CONSETQUENTIAL - * 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, register int base, bool *ok) -{ - register const char *s = nptr; - register TQ_ULLONG acc; - register unsigned char c; - register TQ_ULLONG qbase, cutoff; - register 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, register int base, bool *ok) -{ - register const char *s; - register TQ_ULLONG acc; - register unsigned char c; - register TQ_ULLONG qbase, cutoff; - register 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 TQT_TQLOCALE_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_PRODTQUOT 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(TQ_OS_WIN) || defined(TQ_OS_DARWIN) || defined(TQ_OS_MACX) || \ - defined(mips) || defined(TQ_OS_AIX) || defined(TQ_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_TQDTOA_DEBUG -#include <stdio.h> -#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<const NEEDS_VOLATILE uchar *>(&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<NEEDS_VOLATILE uchar *>(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<const NEEDS_VOLATILE uchar *>(&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<uchar NEEDS_VOLATILE *>(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_PRODTQUOT -#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_TQDTOA_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_TQDTOA_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_TQDTOA_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_TQDTOA_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_PRODTQUOT - && 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_TQDTOA_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_TQDTOA_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 TQ_OS_WIN -#ifndef TQ_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 TQ_OS_LINUX - fenv_t envp; - feholdexcept(&envp); -#endif - - char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp); - -#ifdef TQ_OS_WIN -#ifndef TQ_CC_BOR - _clear87(); -#ifndef _M_X64 - _control87(oldbits, 0xFFFFF); -#else - _control87(oldbits, _MCW_DN|_MCW_EM|_MCW_RC); -#endif //_M_X64 -#endif -#endif - -#ifdef TQ_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 // TQT_TQLOCALE_USES_FCVT |