Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qlocale.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** 
00003 **
00004 ** Implementation of the QLocale class
00005 **
00006 ** Copyright (C) 1992-2003 Trolltech AS.  All rights reserved.
00007 **
00008 ** This file is part of the tools module of the Qt GUI Toolkit.
00009 **
00010 ** This file may be distributed under the terms of the Q Public License
00011 ** as defined by Trolltech AS of Norway and appearing in the file
00012 ** LICENSE.QPL included in the packaging of this file.
00013 **
00014 ** This file may be distributed and/or modified under the terms of the
00015 ** GNU General Public License version 2 as published by the Free Software
00016 ** Foundation and appearing in the file LICENSE.GPL included in the
00017 ** packaging of this file.
00018 **
00019 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00020 ** licenses may use this file in accordance with the Qt Commercial License
00021 ** Agreement provided with the Software.
00022 **
00023 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00024 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00025 **
00026 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00027 **   information about Qt Commercial License Agreements.
00028 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00029 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00030 **
00031 ** Contact info@trolltech.com if any conditions of this licensing are
00032 ** not clear to you.
00033 **
00034 **********************************************************************/
00035 
00036 #include <sys/types.h>
00037 #include <ctype.h>
00038 #include <float.h>
00039 #include <limits.h>
00040 #include <math.h>
00041 #include <stdlib.h>
00042 
00043 #include "qlocale.h"
00044 #include "qlocale_p.h"
00045 
00046 #ifdef QT_QLOCALE_USES_FCVT
00047 # include <qmutex.h>
00048 #endif
00049 
00050 #if defined (Q_WS_WIN)
00051 #   include <windows.h>
00052 // mingw defines NAN and INFINITY to 0/0 and x/0
00053 #   if defined(Q_CC_GNU)
00054 #      undef NAN
00055 #      undef INFINITY
00056 #   else
00057 #      define isnan(d) _isnan(d)
00058 #   endif
00059 #endif
00060 
00061 #if !defined( QWS ) && defined( Q_OS_MAC )
00062 #   include <Carbon/Carbon.h>
00063 #endif
00064 
00065 #if defined (Q_OS_SOLARIS)
00066 #   include <ieeefp.h>
00067 #endif
00068 
00069 #if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX))
00070 #   define INFINITY DBL_INFINITY
00071 #   define NAN DBL_QNAN
00072 #endif
00073 
00074 enum {
00075     LittleEndian,
00076     BigEndian
00077 
00078 #ifdef Q_BYTE_ORDER
00079 #  if Q_BYTE_ORDER == Q_BIG_ENDIAN
00080     , ByteOrder = BigEndian
00081 #  elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
00082     , ByteOrder = LittleEndian
00083 #  else
00084 #    error "undefined byte order"
00085 #  endif
00086 };
00087 #else
00088 };
00089 static const unsigned int one = 1;
00090 static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian);
00091 #endif
00092 
00093 #if !defined(INFINITY)
00094 static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
00095 static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
00096 static inline double inf()
00097 {
00098     return (ByteOrder == BigEndian ?
00099             *((const double *) be_inf_bytes) :
00100             *((const double *) le_inf_bytes));
00101 }
00102 #   define INFINITY (::inf())
00103 #endif
00104 
00105 #if !defined(NAN)
00106 static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
00107 static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
00108 static inline double nan()
00109 {
00110     return (ByteOrder == BigEndian ?
00111             *((const double *) be_nan_bytes) :
00112             *((const double *) le_nan_bytes));
00113 }
00114 #   define NAN (::nan())
00115 #endif
00116 
00117 // Sizes as defined by the ISO C99 standard - fallback
00118 #ifndef LLONG_MAX
00119 #   define LLONG_MAX Q_INT64_C(9223372036854775807)
00120 #endif
00121 #ifndef LLONG_MIN
00122 #   define LLONG_MIN (-LLONG_MAX - Q_INT64_C(1))
00123 #endif
00124 #ifndef ULLONG_MAX
00125 #   define ULLONG_MAX Q_UINT64_C(0xffffffffffffffff)
00126 #endif
00127 
00128 #ifndef QT_QLOCALE_USES_FCVT
00129 static char *qdtoa(double d, int mode, int ndigits, int *decpt,
00130                 int *sign, char **rve, char **digits_str);
00131 static double qstrtod(const char *s00, char const **se, bool *ok);
00132 #endif
00133 static Q_LLONG qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok);
00134 static Q_ULLONG qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok);
00135 
00136 static const uint locale_index[] = {
00137      0, // unused
00138      0, // C
00139      0, // Abkhazian
00140      0, // Afan
00141      0, // Afar
00142      1, // Afrikaans
00143      2, // Albanian
00144      0, // Amharic
00145      3, // Arabic
00146     19, // Armenian
00147      0, // Assamese
00148      0, // Aymara
00149     20, // Azerbaijani
00150      0, // Bashkir
00151     21, // Basque
00152      0, // Bengali
00153      0, // Bhutani
00154      0, // Bihari
00155      0, // Bislama
00156      0, // Breton
00157     22, // Bulgarian
00158      0, // Burmese
00159     23, // Byelorussian
00160      0, // Cambodian
00161     24, // Catalan
00162     25, // Chinese
00163      0, // Corsican
00164     30, // Croatian
00165     31, // Czech
00166     32, // Danish
00167     33, // Dutch
00168     35, // English
00169      0, // Esperanto
00170     47, // Estonian
00171     48, // Faroese
00172      0, // Fiji
00173     49, // Finnish
00174     50, // French
00175      0, // Frisian
00176      0, // Gaelic
00177     56, // Galician
00178     57, // Georgian
00179     58, // German
00180     63, // Greek
00181      0, // Greenlandic
00182      0, // Guarani
00183     64, // Gujarati
00184      0, // Hausa
00185     65, // Hebrew
00186     66, // Hindi
00187     67, // Hungarian
00188     68, // Icelandic
00189     69, // Indonesian
00190      0, // Interlingua
00191      0, // Interlingue
00192      0, // Inuktitut
00193      0, // Inupiak
00194      0, // Irish
00195     70, // Italian
00196     72, // Japanese
00197      0, // Javanese
00198     73, // Kannada
00199      0, // Kashmiri
00200     74, // Kazakh
00201      0, // Kinyarwanda
00202     75, // Kirghiz
00203     76, // Korean
00204      0, // Kurdish
00205      0, // Kurundi
00206      0, // Laothian
00207      0, // Latin
00208     77, // Latvian
00209      0, // Lingala
00210     78, // Lithuanian
00211     79, // Macedonian
00212      0, // Malagasy
00213     80, // Malay
00214      0, // Malayalam
00215      0, // Maltese
00216      0, // Maori
00217     82, // Marathi
00218      0, // Moldavian
00219     83, // Mongolian
00220      0, // Nauru
00221      0, // Nepali
00222     84, // Norwegian
00223      0, // Occitan
00224      0, // Oriya
00225      0, // Pashto
00226     85, // Persian
00227     86, // Polish
00228     87, // Portuguese
00229     89, // Punjabi
00230      0, // Quechua
00231      0, // RhaetoRomance
00232     90, // Romanian
00233     91, // Russian
00234      0, // Samoan
00235      0, // Sangho
00236     92, // Sanskrit
00237      0, // Serbian
00238      0, // SerboCroatian
00239      0, // Sesotho
00240      0, // Setswana
00241      0, // Shona
00242      0, // Sindhi
00243      0, // Singhalese
00244      0, // Siswati
00245     93, // Slovak
00246     94, // Slovenian
00247      0, // Somali
00248     95, // Spanish
00249      0, // Sundanese
00250    114, // Swahili
00251    115, // Swedish
00252      0, // Tagalog
00253      0, // Tajik
00254    117, // Tamil
00255      0, // Tatar
00256    118, // Telugu
00257    119, // Thai
00258      0, // Tibetan
00259      0, // Tigrinya
00260      0, // Tonga
00261      0, // Tsonga
00262    120, // Turkish
00263      0, // Turkmen
00264      0, // Twi
00265      0, // Uigur
00266    121, // Ukrainian
00267    122, // Urdu
00268    123, // Uzbek
00269    124, // Vietnamese
00270      0, // Volapuk
00271      0, // Welsh
00272      0, // Wolof
00273      0, // Xhosa
00274      0, // Yiddish
00275      0, // Yoruba
00276      0, // Zhuang
00277      0, // Zulu
00278      0  // trailing 0
00279 };
00280 
00281 static const QLocalePrivate locale_data[] = {
00282 //      lang   terr    dec  group   list  prcnt   zero  minus    exp
00283     {      1,     0,    46,    44,    59,    37,    48,    45,   101 }, // C/AnyCountry
00284     {      5,   195,    46,    44,    44,    37,    48,    45,   101 }, // Afrikaans/SouthAfrica
00285     {      6,     2,    44,    46,    59,    37,    48,    45,   101 }, // Albanian/Albania
00286     {      8,   186,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/SaudiArabia
00287     {      8,     3,    46,    44,    59,    37,    48,    45,   101 }, // Arabic/Algeria
00288     {      8,    17,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Bahrain
00289     {      8,    64,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Egypt
00290     {      8,   103,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Iraq
00291     {      8,   109,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Jordan
00292     {      8,   115,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Kuwait
00293     {      8,   119,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Lebanon
00294     {      8,   122,    46,    44,    59,    37,    48,    45,   101 }, // Arabic/LibyanArabJamahiriya
00295     {      8,   145,    46,    44,    59,    37,    48,    45,   101 }, // Arabic/Morocco
00296     {      8,   162,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Oman
00297     {      8,   175,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Qatar
00298     {      8,   207,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/SyrianArabRepublic
00299     {      8,   216,    46,    44,    59,    37,    48,    45,   101 }, // Arabic/Tunisia
00300     {      8,   223,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/UnitedArabEmirates
00301     {      8,   237,    46,    44,    59,    37,  1632,    45,   101 }, // Arabic/Yemen
00302     {      9,    11,    46,    44,    44,    37,    48,    45,   101 }, // Armenian/Armenia
00303     {     12,    15,    44,   160,    59,    37,    48,    45,   101 }, // Azerbaijani/Azerbaijan
00304     {     14,   197,    44,    46,    59,    37,    48,    45,   101 }, // Basque/Spain
00305     {     20,    33,    44,   160,    59,    37,    48,    45,   101 }, // Bulgarian/Bulgaria
00306     {     22,    20,    44,   160,    59,    37,    48,    45,   101 }, // Byelorussian/Belarus
00307     {     24,   197,    44,    46,    59,    37,    48,    45,   101 }, // Catalan/Spain
00308     {     25,    44,    46,    44,    44,    37,    48,    45,   101 }, // Chinese/China
00309     {     25,    97,    46,    44,    44,    37,    48,    45,   101 }, // Chinese/HongKong
00310     {     25,   126,    46,    44,    44,    37,    48,    45,   101 }, // Chinese/Macau
00311     {     25,   190,    46,    44,    44,    37,    48,    45,   101 }, // Chinese/Singapore
00312     {     25,   208,    46,    44,    44,    37,    48,    45,   101 }, // Chinese/Taiwan
00313     {     27,    54,    44,    46,    59,    37,    48,    45,   101 }, // Croatian/Croatia
00314     {     28,    57,    44,   160,    59,    37,    48,    45,   101 }, // Czech/CzechRepublic
00315     {     29,    58,    44,    46,    59,    37,    48,    45,   101 }, // Danish/Denmark
00316     {     30,   151,    44,    46,    59,    37,    48,    45,   101 }, // Dutch/Netherlands
00317     {     30,    21,    44,    46,    59,    37,    48,    45,   101 }, // Dutch/Belgium
00318     {     31,   225,    46,    44,    44,    37,    48,    45,   101 }, // English/UnitedStates
00319     {     31,    13,    46,    44,    44,    37,    48,    45,   101 }, // English/Australia
00320     {     31,    22,    46,    44,    59,    37,    48,    45,   101 }, // English/Belize
00321     {     31,    38,    46,    44,    44,    37,    48,    45,   101 }, // English/Canada
00322     {     31,   104,    46,    44,    44,    37,    48,    45,   101 }, // English/Ireland
00323     {     31,   107,    46,    44,    44,    37,    48,    45,   101 }, // English/Jamaica
00324     {     31,   154,    46,    44,    44,    37,    48,    45,   101 }, // English/NewZealand
00325     {     31,   170,    46,    44,    44,    37,    48,    45,   101 }, // English/Philippines
00326     {     31,   195,    46,    44,    44,    37,    48,    45,   101 }, // English/SouthAfrica
00327     {     31,   215,    46,    44,    59,    37,    48,    45,   101 }, // English/TrinidadAndTobago
00328     {     31,   224,    46,    44,    44,    37,    48,    45,   101 }, // English/UnitedKingdom
00329     {     31,   240,    46,    44,    44,    37,    48,    45,   101 }, // English/Zimbabwe
00330     {     33,    68,    44,   160,    59,    37,    48,    45,   101 }, // Estonian/Estonia
00331     {     34,    71,    44,    46,    59,    37,    48,    45,   101 }, // Faroese/FaroeIslands
00332     {     36,    73,    44,   160,    59,    37,    48,    45,   101 }, // Finnish/Finland
00333     {     37,    74,    44,   160,    59,    37,    48,    45,   101 }, // French/France
00334     {     37,    21,    44,    46,    59,    37,    48,    45,   101 }, // French/Belgium
00335     {     37,    38,    44,   160,    59,    37,    48,    45,   101 }, // French/Canada
00336     {     37,   125,    44,   160,    59,    37,    48,    45,   101 }, // French/Luxembourg
00337     {     37,   142,    44,   160,    59,    37,    48,    45,   101 }, // French/Monaco
00338     {     37,   206,    46,    39,    59,    37,    48,    45,   101 }, // French/Switzerland
00339     {     40,   197,    44,    46,    44,    37,    48,    45,   101 }, // Galician/Spain
00340     {     41,    81,    44,   160,    59,    37,    48,    45,   101 }, // Georgian/Georgia
00341     {     42,    82,    44,    46,    59,    37,    48,    45,   101 }, // German/Germany
00342     {     42,    14,    44,    46,    59,    37,    48,    45,   101 }, // German/Austria
00343     {     42,   123,    46,    39,    59,    37,    48,    45,   101 }, // German/Liechtenstein
00344     {     42,   125,    44,    46,    59,    37,    48,    45,   101 }, // German/Luxembourg
00345     {     42,   206,    46,    39,    59,    37,    48,    45,   101 }, // German/Switzerland
00346     {     43,    85,    44,    46,    59,    37,    48,    45,   101 }, // Greek/Greece
00347     {     46,   100,    46,    44,    44,    37,  2790,    45,   101 }, // Gujarati/India
00348     {     48,   105,    46,    44,    44,    37,    48,    45,   101 }, // Hebrew/Israel
00349     {     49,   100,    46,    44,    44,    37,    48,    45,   101 }, // Hindi/India
00350     {     50,    98,    44,   160,    59,    37,    48,    45,   101 }, // Hungarian/Hungary
00351     {     51,    99,    44,    46,    59,    37,    48,    45,   101 }, // Icelandic/Iceland
00352     {     52,   101,    44,    46,    59,    37,    48,    45,   101 }, // Indonesian/Indonesia
00353     {     58,   106,    44,    46,    59,    37,    48,    45,   101 }, // Italian/Italy
00354     {     58,   206,    46,    39,    59,    37,    48,    45,   101 }, // Italian/Switzerland
00355     {     59,   108,    46,    44,    44,    37,    48,    45,   101 }, // Japanese/Japan
00356     {     61,   100,    46,    44,    44,    37,  3302,    45,   101 }, // Kannada/India
00357     {     63,   110,    44,   160,    59,    37,    48,    45,   101 }, // Kazakh/Kazakhstan
00358     {     65,   116,    44,   160,    59,    37,    48,    45,   101 }, // Kirghiz/Kyrgyzstan
00359     {     66,   114,    46,    44,    44,    37,    48,    45,   101 }, // Korean/RepublicOfKorea
00360     {     71,   118,    44,   160,    59,    37,    48,    45,   101 }, // Latvian/Latvia
00361     {     73,   124,    44,    46,    59,    37,    48,    45,   101 }, // Lithuanian/Lithuania
00362     {     74,   127,    44,    46,    59,    37,    48,    45,   101 }, // Macedonian/Macedonia
00363     {     76,   130,    44,    46,    59,    37,    48,    45,   101 }, // Malay/Malaysia
00364     {     76,    32,    44,    46,    59,    37,    48,    45,   101 }, // Malay/BruneiDarussalam
00365     {     80,   100,    46,    44,    44,    37,  2406,    45,   101 }, // Marathi/India
00366     {     82,   143,    44,   160,    59,    37,    48,    45,   101 }, // Mongolian/Mongolia
00367     {     85,   161,    44,   160,    59,    37,    48,    45,   101 }, // Norwegian/Norway
00368     {     89,   102,    46,    44,    59,    37,  1776,    45,   101 }, // Persian/Iran
00369     {     90,   172,    44,   160,    59,    37,    48,    45,   101 }, // Polish/Poland
00370     {     91,   173,    44,    46,    59,    37,    48,    45,   101 }, // Portuguese/Portugal
00371     {     91,    30,    44,    46,    59,    37,    48,    45,   101 }, // Portuguese/Brazil
00372     {     92,   100,    46,    44,    44,    37,  2662,    45,   101 }, // Punjabi/India
00373     {     95,   177,    44,    46,    59,    37,    48,    45,   101 }, // Romanian/Romania
00374     {     96,   178,    44,   160,    59,    37,    48,    45,   101 }, // Russian/RussianFederation
00375     {     99,   100,    46,    44,    44,    37,  2406,    45,   101 }, // Sanskrit/India
00376     {    108,   191,    44,   160,    59,    37,    48,    45,   101 }, // Slovak/Slovakia
00377     {    109,   192,    44,    46,    59,    37,    48,    45,   101 }, // Slovenian/Slovenia
00378     {    111,   197,    44,    46,    59,    37,    48,    45,   101 }, // Spanish/Spain
00379     {    111,    10,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Argentina
00380     {    111,    26,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Bolivia
00381     {    111,    43,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Chile
00382     {    111,    47,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Colombia
00383     {    111,    52,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/CostaRica
00384     {    111,    61,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/DominicanRepublic
00385     {    111,    63,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Ecuador
00386     {    111,    65,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/ElSalvador
00387     {    111,    90,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/Guatemala
00388     {    111,    96,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/Honduras
00389     {    111,   139,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/Mexico
00390     {    111,   155,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/Nicaragua
00391     {    111,   166,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/Panama
00392     {    111,   168,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Paraguay
00393     {    111,   169,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/Peru
00394     {    111,   174,    46,    44,    44,    37,    48,    45,   101 }, // Spanish/PuertoRico
00395     {    111,   227,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Uruguay
00396     {    111,   231,    44,    46,    44,    37,    48,    45,   101 }, // Spanish/Venezuela
00397     {    113,   111,    46,    44,    44,    37,    48,    45,   101 }, // Swahili/Kenya
00398     {    114,   205,    44,   160,    59,    37,    48,    45,   101 }, // Swedish/Sweden
00399     {    114,    73,    44,   160,    59,    37,    48,    45,   101 }, // Swedish/Finland
00400     {    117,   100,    46,    44,    44,    37,    48,    45,   101 }, // Tamil/India
00401     {    119,   100,    46,    44,    44,    37,  3174,    45,   101 }, // Telugu/India
00402     {    120,   211,    46,    44,    44,    37,  3664,    45,   101 }, // Thai/Thailand
00403     {    125,   217,    44,    46,    59,    37,    48,    45,   101 }, // Turkish/Turkey
00404     {    129,   222,    44,   160,    59,    37,    48,    45,   101 }, // Ukrainian/Ukraine
00405     {    130,   163,    46,    44,    59,    37,  1776,    45,   101 }, // Urdu/Pakistan
00406     {    131,   228,    44,   160,    59,    37,    48,    45,   101 }, // Uzbek/Uzbekistan
00407     {    132,   232,    44,    46,    44,    37,    48,    45,   101 }, // Vietnamese/VietNam
00408     {      0,     0,     0,     0,     0,     0,     0,     0,     0 }  // trailing 0s
00409 };
00410 
00411 static const char language_name_list[] =
00412 "Default\0"
00413 "C\0"
00414 "Abkhazian\0"
00415 "Afan\0"
00416 "Afar\0"
00417 "Afrikaans\0"
00418 "Albanian\0"
00419 "Amharic\0"
00420 "Arabic\0"
00421 "Armenian\0"
00422 "Assamese\0"
00423 "Aymara\0"
00424 "Azerbaijani\0"
00425 "Bashkir\0"
00426 "Basque\0"
00427 "Bengali\0"
00428 "Bhutani\0"
00429 "Bihari\0"
00430 "Bislama\0"
00431 "Breton\0"
00432 "Bulgarian\0"
00433 "Burmese\0"
00434 "Byelorussian\0"
00435 "Cambodian\0"
00436 "Catalan\0"
00437 "Chinese\0"
00438 "Corsican\0"
00439 "Croatian\0"
00440 "Czech\0"
00441 "Danish\0"
00442 "Dutch\0"
00443 "English\0"
00444 "Esperanto\0"
00445 "Estonian\0"
00446 "Faroese\0"
00447 "Fiji\0"
00448 "Finnish\0"
00449 "French\0"
00450 "Frisian\0"
00451 "Gaelic\0"
00452 "Galician\0"
00453 "Georgian\0"
00454 "German\0"
00455 "Greek\0"
00456 "Greenlandic\0"
00457 "Guarani\0"
00458 "Gujarati\0"
00459 "Hausa\0"
00460 "Hebrew\0"
00461 "Hindi\0"
00462 "Hungarian\0"
00463 "Icelandic\0"
00464 "Indonesian\0"
00465 "Interlingua\0"
00466 "Interlingue\0"
00467 "Inuktitut\0"
00468 "Inupiak\0"
00469 "Irish\0"
00470 "Italian\0"
00471 "Japanese\0"
00472 "Javanese\0"
00473 "Kannada\0"
00474 "Kashmiri\0"
00475 "Kazakh\0"
00476 "Kinyarwanda\0"
00477 "Kirghiz\0"
00478 "Korean\0"
00479 "Kurdish\0"
00480 "Kurundi\0"
00481 "Laothian\0"
00482 "Latin\0"
00483 "Latvian\0"
00484 "Lingala\0"
00485 "Lithuanian\0"
00486 "Macedonian\0"
00487 "Malagasy\0"
00488 "Malay\0"
00489 "Malayalam\0"
00490 "Maltese\0"
00491 "Maori\0"
00492 "Marathi\0"
00493 "Moldavian\0"
00494 "Mongolian\0"
00495 "Nauru\0"
00496 "Nepali\0"
00497 "Norwegian\0"
00498 "Occitan\0"
00499 "Oriya\0"
00500 "Pashto\0"
00501 "Persian\0"
00502 "Polish\0"
00503 "Portuguese\0"
00504 "Punjabi\0"
00505 "Quechua\0"
00506 "RhaetoRomance\0"
00507 "Romanian\0"
00508 "Russian\0"
00509 "Samoan\0"
00510 "Sangho\0"
00511 "Sanskrit\0"
00512 "Serbian\0"
00513 "SerboCroatian\0"
00514 "Sesotho\0"
00515 "Setswana\0"
00516 "Shona\0"
00517 "Sindhi\0"
00518 "Singhalese\0"
00519 "Siswati\0"
00520 "Slovak\0"
00521 "Slovenian\0"
00522 "Somali\0"
00523 "Spanish\0"
00524 "Sundanese\0"
00525 "Swahili\0"
00526 "Swedish\0"
00527 "Tagalog\0"
00528 "Tajik\0"
00529 "Tamil\0"
00530 "Tatar\0"
00531 "Telugu\0"
00532 "Thai\0"
00533 "Tibetan\0"
00534 "Tigrinya\0"
00535 "Tonga\0"
00536 "Tsonga\0"
00537 "Turkish\0"
00538 "Turkmen\0"
00539 "Twi\0"
00540 "Uigur\0"
00541 "Ukrainian\0"
00542 "Urdu\0"
00543 "Uzbek\0"
00544 "Vietnamese\0"
00545 "Volapuk\0"
00546 "Welsh\0"
00547 "Wolof\0"
00548 "Xhosa\0"
00549 "Yiddish\0"
00550 "Yoruba\0"
00551 "Zhuang\0"
00552 "Zulu\0";
00553 
00554 static const uint language_name_index[] = {
00555      0, // Unused
00556      8, // C
00557     10, // Abkhazian
00558     20, // Afan
00559     25, // Afar
00560     30, // Afrikaans
00561     40, // Albanian
00562     49, // Amharic
00563     57, // Arabic
00564     64, // Armenian
00565     73, // Assamese
00566     82, // Aymara
00567     89, // Azerbaijani
00568    101, // Bashkir
00569    109, // Basque
00570    116, // Bengali
00571    124, // Bhutani
00572    132, // Bihari
00573    139, // Bislama
00574    147, // Breton
00575    154, // Bulgarian
00576    164, // Burmese
00577    172, // Byelorussian
00578    185, // Cambodian
00579    195, // Catalan
00580    203, // Chinese
00581    211, // Corsican
00582    220, // Croatian
00583    229, // Czech
00584    235, // Danish
00585    242, // Dutch
00586    248, // English
00587    256, // Esperanto
00588    266, // Estonian
00589    275, // Faroese
00590    283, // Fiji
00591    288, // Finnish
00592    296, // French
00593    303, // Frisian
00594    311, // Gaelic
00595    318, // Galician
00596    327, // Georgian
00597    336, // German
00598    343, // Greek
00599    349, // Greenlandic
00600    361, // Guarani
00601    369, // Gujarati
00602    378, // Hausa
00603    384, // Hebrew
00604    391, // Hindi
00605    397, // Hungarian
00606    407, // Icelandic
00607    417, // Indonesian
00608    428, // Interlingua
00609    440, // Interlingue
00610    452, // Inuktitut
00611    462, // Inupiak
00612    470, // Irish
00613    476, // Italian
00614    484, // Japanese
00615    493, // Javanese
00616    502, // Kannada
00617    510, // Kashmiri
00618    519, // Kazakh
00619    526, // Kinyarwanda
00620    538, // Kirghiz
00621    546, // Korean
00622    553, // Kurdish
00623    561, // Kurundi
00624    569, // Laothian
00625    578, // Latin
00626    584, // Latvian
00627    592, // Lingala
00628    600, // Lithuanian
00629    611, // Macedonian
00630    622, // Malagasy
00631    631, // Malay
00632    637, // Malayalam
00633    647, // Maltese
00634    655, // Maori
00635    661, // Marathi
00636    669, // Moldavian
00637    679, // Mongolian
00638    689, // Nauru
00639    695, // Nepali
00640    702, // Norwegian
00641    712, // Occitan
00642    720, // Oriya
00643    726, // Pashto
00644    733, // Persian
00645    741, // Polish
00646    748, // Portuguese
00647    759, // Punjabi
00648    767, // Quechua
00649    775, // RhaetoRomance
00650    789, // Romanian
00651    798, // Russian
00652    806, // Samoan
00653    813, // Sangho
00654    820, // Sanskrit
00655    829, // Serbian
00656    837, // SerboCroatian
00657    851, // Sesotho
00658    859, // Setswana
00659    868, // Shona
00660    874, // Sindhi
00661    881, // Singhalese
00662    892, // Siswati
00663    900, // Slovak
00664    907, // Slovenian
00665    917, // Somali
00666    924, // Spanish
00667    932, // Sundanese
00668    942, // Swahili
00669    950, // Swedish
00670    958, // Tagalog
00671    966, // Tajik
00672    972, // Tamil
00673    978, // Tatar
00674    984, // Telugu
00675    991, // Thai
00676    996, // Tibetan
00677   1004, // Tigrinya
00678   1013, // Tonga
00679   1019, // Tsonga
00680   1026, // Turkish
00681   1034, // Turkmen
00682   1042, // Twi
00683   1046, // Uigur
00684   1052, // Ukrainian
00685   1062, // Urdu
00686   1067, // Uzbek
00687   1073, // Vietnamese
00688   1084, // Volapuk
00689   1092, // Welsh
00690   1098, // Wolof
00691   1104, // Xhosa
00692   1110, // Yiddish
00693   1118, // Yoruba
00694   1125, // Zhuang
00695   1132  // Zulu
00696 };
00697 
00698 static const char country_name_list[] =
00699 "Default\0"
00700 "Afghanistan\0"
00701 "Albania\0"
00702 "Algeria\0"
00703 "AmericanSamoa\0"
00704 "Andorra\0"
00705 "Angola\0"
00706 "Anguilla\0"
00707 "Antarctica\0"
00708 "AntiguaAndBarbuda\0"
00709 "Argentina\0"
00710 "Armenia\0"
00711 "Aruba\0"
00712 "Australia\0"
00713 "Austria\0"
00714 "Azerbaijan\0"
00715 "Bahamas\0"
00716 "Bahrain\0"
00717 "Bangladesh\0"
00718 "Barbados\0"
00719 "Belarus\0"
00720 "Belgium\0"
00721 "Belize\0"
00722 "Benin\0"
00723 "Bermuda\0"
00724 "Bhutan\0"
00725 "Bolivia\0"
00726 "BosniaAndHerzegowina\0"
00727 "Botswana\0"
00728 "BouvetIsland\0"
00729 "Brazil\0"
00730 "BritishIndianOceanTerritory\0"
00731 "BruneiDarussalam\0"
00732 "Bulgaria\0"
00733 "BurkinaFaso\0"
00734 "Burundi\0"
00735 "Cambodia\0"
00736 "Cameroon\0"
00737 "Canada\0"
00738 "CapeVerde\0"
00739 "CaymanIslands\0"
00740 "CentralAfricanRepublic\0"
00741 "Chad\0"
00742 "Chile\0"
00743 "China\0"
00744 "ChristmasIsland\0"
00745 "CocosIslands\0"
00746 "Colombia\0"
00747 "Comoros\0"
00748 "DemocraticRepublicOfCongo\0"
00749 "PeoplesRepublicOfCongo\0"
00750 "CookIslands\0"
00751 "CostaRica\0"
00752 "IvoryCoast\0"
00753 "Croatia\0"
00754 "Cuba\0"
00755 "Cyprus\0"
00756 "CzechRepublic\0"
00757 "Denmark\0"
00758 "Djibouti\0"
00759 "Dominica\0"
00760 "DominicanRepublic\0"
00761 "EastTimor\0"
00762 "Ecuador\0"
00763 "Egypt\0"
00764 "ElSalvador\0"
00765 "EquatorialGuinea\0"
00766 "Eritrea\0"
00767 "Estonia\0"
00768 "Ethiopia\0"
00769 "FalklandIslands\0"
00770 "FaroeIslands\0"
00771 "Fiji\0"
00772 "Finland\0"
00773 "France\0"
00774 "MetropolitanFrance\0"
00775 "FrenchGuiana\0"
00776 "FrenchPolynesia\0"
00777 "FrenchSouthernTerritories\0"
00778 "Gabon\0"
00779 "Gambia\0"
00780 "Georgia\0"
00781 "Germany\0"
00782 "Ghana\0"
00783 "Gibraltar\0"
00784 "Greece\0"
00785 "Greenland\0"
00786 "Grenada\0"
00787 "Guadeloupe\0"
00788 "Guam\0"
00789 "Guatemala\0"
00790 "Guinea\0"
00791 "GuineaBissau\0"
00792 "Guyana\0"
00793 "Haiti\0"
00794 "HeardAndMcDonaldIslands\0"
00795 "Honduras\0"
00796 "HongKong\0"
00797 "Hungary\0"
00798 "Iceland\0"
00799 "India\0"
00800 "Indonesia\0"
00801 "Iran\0"
00802 "Iraq\0"
00803 "Ireland\0"
00804 "Israel\0"
00805 "Italy\0"
00806 "Jamaica\0"
00807 "Japan\0"
00808 "Jordan\0"
00809 "Kazakhstan\0"
00810 "Kenya\0"
00811 "Kiribati\0"
00812 "DemocraticRepublicOfKorea\0"
00813 "RepublicOfKorea\0"
00814 "Kuwait\0"
00815 "Kyrgyzstan\0"
00816 "Lao\0"
00817 "Latvia\0"
00818 "Lebanon\0"
00819 "Lesotho\0"
00820 "Liberia\0"
00821 "LibyanArabJamahiriya\0"
00822 "Liechtenstein\0"
00823 "Lithuania\0"
00824 "Luxembourg\0"
00825 "Macau\0"
00826 "Macedonia\0"
00827 "Madagascar\0"
00828 "Malawi\0"
00829 "Malaysia\0"
00830 "Maldives\0"
00831 "Mali\0"
00832 "Malta\0"
00833 "MarshallIslands\0"
00834 "Martinique\0"
00835 "Mauritania\0"
00836 "Mauritius\0"
00837 "Mayotte\0"
00838 "Mexico\0"
00839 "Micronesia\0"
00840 "Moldova\0"
00841 "Monaco\0"
00842 "Mongolia\0"
00843 "Montserrat\0"
00844 "Morocco\0"
00845 "Mozambique\0"
00846 "Myanmar\0"
00847 "Namibia\0"
00848 "Nauru\0"
00849 "Nepal\0"
00850 "Netherlands\0"
00851 "NetherlandsAntilles\0"
00852 "NewCaledonia\0"
00853 "NewZealand\0"
00854 "Nicaragua\0"
00855 "Niger\0"
00856 "Nigeria\0"
00857 "Niue\0"
00858 "NorfolkIsland\0"
00859 "NorthernMarianaIslands\0"
00860 "Norway\0"
00861 "Oman\0"
00862 "Pakistan\0"
00863 "Palau\0"
00864 "PalestinianTerritory\0"
00865 "Panama\0"
00866 "PapuaNewGuinea\0"
00867 "Paraguay\0"
00868 "Peru\0"
00869 "Philippines\0"
00870 "Pitcairn\0"
00871 "Poland\0"
00872 "Portugal\0"
00873 "PuertoRico\0"
00874 "Qatar\0"
00875 "Reunion\0"
00876 "Romania\0"
00877 "RussianFederation\0"
00878 "Rwanda\0"
00879 "SaintKittsAndNevis\0"
00880 "StLucia\0"
00881 "StVincentAndTheGrenadines\0"
00882 "Samoa\0"
00883 "SanMarino\0"
00884 "SaoTomeAndPrincipe\0"
00885 "SaudiArabia\0"
00886 "Senegal\0"
00887 "Seychelles\0"
00888 "SierraLeone\0"
00889 "Singapore\0"
00890 "Slovakia\0"
00891 "Slovenia\0"
00892 "SolomonIslands\0"
00893 "Somalia\0"
00894 "SouthAfrica\0"
00895 "SouthGeorgiaAndTheSouthSandwichIslands\0"
00896 "Spain\0"
00897 "SriLanka\0"
00898 "StHelena\0"
00899 "StPierreAndMiquelon\0"
00900 "Sudan\0"
00901 "Suriname\0"
00902 "SvalbardAndJanMayenIslands\0"
00903 "Swaziland\0"
00904 "Sweden\0"
00905 "Switzerland\0"
00906 "SyrianArabRepublic\0"
00907 "Taiwan\0"
00908 "Tajikistan\0"
00909 "Tanzania\0"
00910 "Thailand\0"
00911 "Togo\0"
00912 "Tokelau\0"
00913 "Tonga\0"
00914 "TrinidadAndTobago\0"
00915 "Tunisia\0"
00916 "Turkey\0"
00917 "Turkmenistan\0"
00918 "TurksAndCaicosIslands\0"
00919 "Tuvalu\0"
00920 "Uganda\0"
00921 "Ukraine\0"
00922 "UnitedArabEmirates\0"
00923 "UnitedKingdom\0"
00924 "UnitedStates\0"
00925 "UnitedStatesMinorOutlyingIslands\0"
00926 "Uruguay\0"
00927 "Uzbekistan\0"
00928 "Vanuatu\0"
00929 "VaticanCityState\0"
00930 "Venezuela\0"
00931 "VietNam\0"
00932 "BritishVirginIslands\0"
00933 "USVirginIslands\0"
00934 "WallisAndFutunaIslands\0"
00935 "WesternSahara\0"
00936 "Yemen\0"
00937 "Yugoslavia\0"
00938 "Zambia\0"
00939 "Zimbabwe\0";
00940 
00941 static const uint country_name_index[] = {
00942      0, // AnyCountry
00943      8, // Afghanistan
00944     20, // Albania
00945     28, // Algeria
00946     36, // AmericanSamoa
00947     50, // Andorra
00948     58, // Angola
00949     65, // Anguilla
00950     74, // Antarctica
00951     85, // AntiguaAndBarbuda
00952    103, // Argentina
00953    113, // Armenia
00954    121, // Aruba
00955    127, // Australia
00956    137, // Austria
00957    145, // Azerbaijan
00958    156, // Bahamas
00959    164, // Bahrain
00960    172, // Bangladesh
00961    183, // Barbados
00962    192, // Belarus
00963    200, // Belgium
00964    208, // Belize
00965    215, // Benin
00966    221, // Bermuda
00967    229, // Bhutan
00968    236, // Bolivia
00969    244, // BosniaAndHerzegowina
00970    265, // Botswana
00971    274, // BouvetIsland
00972    287, // Brazil
00973    294, // BritishIndianOceanTerritory
00974    322, // BruneiDarussalam
00975    339, // Bulgaria
00976    348, // BurkinaFaso
00977    360, // Burundi
00978    368, // Cambodia
00979    377, // Cameroon
00980    386, // Canada
00981    393, // CapeVerde
00982    403, // CaymanIslands
00983    417, // CentralAfricanRepublic
00984    440, // Chad
00985    445, // Chile
00986    451, // China
00987    457, // ChristmasIsland
00988    473, // CocosIslands
00989    486, // Colombia
00990    495, // Comoros
00991    503, // DemocraticRepublicOfCongo
00992    529, // PeoplesRepublicOfCongo
00993    552, // CookIslands
00994    564, // CostaRica
00995    574, // IvoryCoast
00996    585, // Croatia
00997    593, // Cuba
00998    598, // Cyprus
00999    605, // CzechRepublic
01000    619, // Denmark
01001    627, // Djibouti
01002    636, // Dominica
01003    645, // DominicanRepublic
01004    663, // EastTimor
01005    673, // Ecuador
01006    681, // Egypt
01007    687, // ElSalvador
01008    698, // EquatorialGuinea
01009    715, // Eritrea
01010    723, // Estonia
01011    731, // Ethiopia
01012    740, // FalklandIslands
01013    756, // FaroeIslands
01014    769, // Fiji
01015    774, // Finland
01016    782, // France
01017    789, // MetropolitanFrance
01018    808, // FrenchGuiana
01019    821, // FrenchPolynesia
01020    837, // FrenchSouthernTerritories
01021    863, // Gabon
01022    869, // Gambia
01023    876, // Georgia
01024    884, // Germany
01025    892, // Ghana
01026    898, // Gibraltar
01027    908, // Greece
01028    915, // Greenland
01029    925, // Grenada
01030    933, // Guadeloupe
01031    944, // Guam
01032    949, // Guatemala
01033    959, // Guinea
01034    966, // GuineaBissau
01035    979, // Guyana
01036    986, // Haiti
01037    992, // HeardAndMcDonaldIslands
01038   1016, // Honduras
01039   1025, // HongKong
01040   1034, // Hungary
01041   1042, // Iceland
01042   1050, // India
01043   1056, // Indonesia
01044   1066, // Iran
01045   1071, // Iraq
01046   1076, // Ireland
01047   1084, // Israel
01048   1091, // Italy
01049   1097, // Jamaica
01050   1105, // Japan
01051   1111, // Jordan
01052   1118, // Kazakhstan
01053   1129, // Kenya
01054   1135, // Kiribati
01055   1144, // DemocraticRepublicOfKorea
01056   1170, // RepublicOfKorea
01057   1186, // Kuwait
01058   1193, // Kyrgyzstan
01059   1204, // Lao
01060   1208, // Latvia
01061   1215, // Lebanon
01062   1223, // Lesotho
01063   1231, // Liberia
01064   1239, // LibyanArabJamahiriya
01065   1260, // Liechtenstein
01066   1274, // Lithuania
01067   1284, // Luxembourg
01068   1295, // Macau
01069   1301, // Macedonia
01070   1311, // Madagascar
01071   1322, // Malawi
01072   1329, // Malaysia
01073   1338, // Maldives
01074   1347, // Mali
01075   1352, // Malta
01076   1358, // MarshallIslands
01077   1374, // Martinique
01078   1385, // Mauritania
01079   1396, // Mauritius
01080   1406, // Mayotte
01081   1414, // Mexico
01082   1421, // Micronesia
01083   1432, // Moldova
01084   1440, // Monaco
01085   1447, // Mongolia
01086   1456, // Montserrat
01087   1467, // Morocco
01088   1475, // Mozambique
01089   1486, // Myanmar
01090   1494, // Namibia
01091   1502, // Nauru
01092   1508, // Nepal
01093   1514, // Netherlands
01094   1526, // NetherlandsAntilles
01095   1546, // NewCaledonia
01096   1559, // NewZealand
01097   1570, // Nicaragua
01098   1580, // Niger
01099   1586, // Nigeria
01100   1594, // Niue
01101   1599, // NorfolkIsland
01102   1613, // NorthernMarianaIslands
01103   1636, // Norway
01104   1643, // Oman
01105   1648, // Pakistan
01106   1657, // Palau
01107   1663, // PalestinianTerritory
01108   1684, // Panama
01109   1691, // PapuaNewGuinea
01110   1706, // Paraguay
01111   1715, // Peru
01112   1720, // Philippines
01113   1732, // Pitcairn
01114   1741, // Poland
01115   1748, // Portugal
01116   1757, // PuertoRico
01117   1768, // Qatar
01118   1774, // Reunion
01119   1782, // Romania
01120   1790, // RussianFederation
01121   1808, // Rwanda
01122   1815, // SaintKittsAndNevis
01123   1834, // StLucia
01124   1842, // StVincentAndTheGrenadines
01125   1868, // Samoa
01126   1874, // SanMarino
01127   1884, // SaoTomeAndPrincipe
01128   1903, // SaudiArabia
01129   1915, // Senegal
01130   1923, // Seychelles
01131   1934, // SierraLeone
01132   1946, // Singapore
01133   1956, // Slovakia
01134   1965, // Slovenia
01135   1974, // SolomonIslands
01136   1989, // Somalia
01137   1997, // SouthAfrica
01138   2009, // SouthGeorgiaAndTheSouthSandwichIslands
01139   2048, // Spain
01140   2054, // SriLanka
01141   2063, // StHelena
01142   2072, // StPierreAndMiquelon
01143   2092, // Sudan
01144   2098, // Suriname
01145   2107, // SvalbardAndJanMayenIslands
01146   2134, // Swaziland
01147   2144, // Sweden
01148   2151, // Switzerland
01149   2163, // SyrianArabRepublic
01150   2182, // Taiwan
01151   2189, // Tajikistan
01152   2200, // Tanzania
01153   2209, // Thailand
01154   2218, // Togo
01155   2223, // Tokelau
01156   2231, // Tonga
01157   2237, // TrinidadAndTobago
01158   2255, // Tunisia
01159   2263, // Turkey
01160   2270, // Turkmenistan
01161   2283, // TurksAndCaicosIslands
01162   2305, // Tuvalu
01163   2312, // Uganda
01164   2319, // Ukraine
01165   2327, // UnitedArabEmirates
01166   2346, // UnitedKingdom
01167   2360, // UnitedStates
01168   2373, // UnitedStatesMinorOutlyingIslands
01169   2406, // Uruguay
01170   2414, // Uzbekistan
01171   2425, // Vanuatu
01172   2433, // VaticanCityState
01173   2450, // Venezuela
01174   2460, // VietNam
01175   2468, // BritishVirginIslands
01176   2489, // USVirginIslands
01177   2505, // WallisAndFutunaIslands
01178   2528, // WesternSahara
01179   2542, // Yemen
01180   2548, // Yugoslavia
01181   2559, // Zambia
01182   2566  // Zimbabwe
01183 };
01184 
01185 static const char language_code_list[] =
01186 "  " // Unused
01187 "  " // C
01188 "ab" // Abkhazian
01189 "om" // Afan
01190 "aa" // Afar
01191 "af" // Afrikaans
01192 "sq" // Albanian
01193 "am" // Amharic
01194 "ar" // Arabic
01195 "hy" // Armenian
01196 "as" // Assamese
01197 "ay" // Aymara
01198 "az" // Azerbaijani
01199 "ba" // Bashkir
01200 "eu" // Basque
01201 "bn" // Bengali
01202 "dz" // Bhutani
01203 "bh" // Bihari
01204 "bi" // Bislama
01205 "br" // Breton
01206 "bg" // Bulgarian
01207 "my" // Burmese
01208 "be" // Byelorussian
01209 "km" // Cambodian
01210 "ca" // Catalan
01211 "zh" // Chinese
01212 "co" // Corsican
01213 "hr" // Croatian
01214 "cs" // Czech
01215 "da" // Danish
01216 "nl" // Dutch
01217 "en" // English
01218 "eo" // Esperanto
01219 "et" // Estonian
01220 "fo" // Faroese
01221 "fj" // Fiji
01222 "fi" // Finnish
01223 "fr" // French
01224 "fy" // Frisian
01225 "gd" // Gaelic
01226 "gl" // Galician
01227 "ka" // Georgian
01228 "de" // German
01229 "el" // Greek
01230 "kl" // Greenlandic
01231 "gn" // Guarani
01232 "gu" // Gujarati
01233 "ha" // Hausa
01234 "he" // Hebrew
01235 "hi" // Hindi
01236 "hu" // Hungarian
01237 "is" // Icelandic
01238 "id" // Indonesian
01239 "ia" // Interlingua
01240 "ie" // Interlingue
01241 "iu" // Inuktitut
01242 "ik" // Inupiak
01243 "ga" // Irish
01244 "it" // Italian
01245 "ja" // Japanese
01246 "jv" // Javanese
01247 "kn" // Kannada
01248 "ks" // Kashmiri
01249 "kk" // Kazakh
01250 "rw" // Kinyarwanda
01251 "ky" // Kirghiz
01252 "ko" // Korean
01253 "ku" // Kurdish
01254 "rn" // Kurundi
01255 "lo" // Laothian
01256 "la" // Latin
01257 "lv" // Latvian
01258 "ln" // Lingala
01259 "lt" // Lithuanian
01260 "mk" // Macedonian
01261 "mg" // Malagasy
01262 "ms" // Malay
01263 "ml" // Malayalam
01264 "mt" // Maltese
01265 "mi" // Maori
01266 "mr" // Marathi
01267 "mo" // Moldavian
01268 "mn" // Mongolian
01269 "na" // Nauru
01270 "ne" // Nepali
01271 "no" // Norwegian
01272 "oc" // Occitan
01273 "or" // Oriya
01274 "ps" // Pashto
01275 "fa" // Persian
01276 "pl" // Polish
01277 "pt" // Portuguese
01278 "pa" // Punjabi
01279 "qu" // Quechua
01280 "rm" // RhaetoRomance
01281 "ro" // Romanian
01282 "ru" // Russian
01283 "sm" // Samoan
01284 "sg" // Sangho
01285 "sa" // Sanskrit
01286 "sr" // Serbian
01287 "sh" // SerboCroatian
01288 "st" // Sesotho
01289 "tn" // Setswana
01290 "sn" // Shona
01291 "sd" // Sindhi
01292 "si" // Singhalese
01293 "ss" // Siswati
01294 "sk" // Slovak
01295 "sl" // Slovenian
01296 "so" // Somali
01297 "es" // Spanish
01298 "su" // Sundanese
01299 "sw" // Swahili
01300 "sv" // Swedish
01301 "tl" // Tagalog
01302 "tg" // Tajik
01303 "ta" // Tamil
01304 "tt" // Tatar
01305 "te" // Telugu
01306 "th" // Thai
01307 "bo" // Tibetan
01308 "ti" // Tigrinya
01309 "to" // Tonga
01310 "ts" // Tsonga
01311 "tr" // Turkish
01312 "tk" // Turkmen
01313 "tw" // Twi
01314 "ug" // Uigur
01315 "uk" // Ukrainian
01316 "ur" // Urdu
01317 "uz" // Uzbek
01318 "vi" // Vietnamese
01319 "vo" // Volapuk
01320 "cy" // Welsh
01321 "wo" // Wolof
01322 "xh" // Xhosa
01323 "yi" // Yiddish
01324 "yo" // Yoruba
01325 "za" // Zhuang
01326 "zu" // Zulu
01327 ;
01328 
01329 static const char country_code_list[] =
01330 "  " // AnyLanguage
01331 "AF" // Afghanistan
01332 "AL" // Albania
01333 "DZ" // Algeria
01334 "AS" // AmericanSamoa
01335 "AD" // Andorra
01336 "AO" // Angola
01337 "AI" // Anguilla
01338 "AQ" // Antarctica
01339 "AG" // AntiguaAndBarbuda
01340 "AR" // Argentina
01341 "AM" // Armenia
01342 "AW" // Aruba
01343 "AU" // Australia
01344 "AT" // Austria
01345 "AZ" // Azerbaijan
01346 "BS" // Bahamas
01347 "BH" // Bahrain
01348 "BD" // Bangladesh
01349 "BB" // Barbados
01350 "BY" // Belarus
01351 "BE" // Belgium
01352 "BZ" // Belize
01353 "BJ" // Benin
01354 "BM" // Bermuda
01355 "BT" // Bhutan
01356 "BO" // Bolivia
01357 "BA" // BosniaAndHerzegowina
01358 "BW" // Botswana
01359 "BV" // BouvetIsland
01360 "BR" // Brazil
01361 "IO" // BritishIndianOceanTerritory
01362 "BN" // BruneiDarussalam
01363 "BG" // Bulgaria
01364 "BF" // BurkinaFaso
01365 "BI" // Burundi
01366 "KH" // Cambodia
01367 "CM" // Cameroon
01368 "CA" // Canada
01369 "CV" // CapeVerde
01370 "KY" // CaymanIslands
01371 "CF" // CentralAfricanRepublic
01372 "TD" // Chad
01373 "CL" // Chile
01374 "CN" // China
01375 "CX" // ChristmasIsland
01376 "CC" // CocosIslands
01377 "CO" // Colombia
01378 "KM" // Comoros
01379 "CD" // DemocraticRepublicOfCongo
01380 "CG" // PeoplesRepublicOfCongo
01381 "CK" // CookIslands
01382 "CR" // CostaRica
01383 "CI" // IvoryCoast
01384 "HR" // Croatia
01385 "CU" // Cuba
01386 "CY" // Cyprus
01387 "CZ" // CzechRepublic
01388 "DK" // Denmark
01389 "DJ" // Djibouti
01390 "DM" // Dominica
01391 "DO" // DominicanRepublic
01392 "TL" // EastTimor
01393 "EC" // Ecuador
01394 "EG" // Egypt
01395 "SV" // ElSalvador
01396 "GQ" // EquatorialGuinea
01397 "ER" // Eritrea
01398 "EE" // Estonia
01399 "ET" // Ethiopia
01400 "FK" // FalklandIslands
01401 "FO" // FaroeIslands
01402 "FJ" // Fiji
01403 "FI" // Finland
01404 "FR" // France
01405 "FX" // MetropolitanFrance
01406 "GF" // FrenchGuiana
01407 "PF" // FrenchPolynesia
01408 "TF" // FrenchSouthernTerritories
01409 "GA" // Gabon
01410 "GM" // Gambia
01411 "GE" // Georgia
01412 "DE" // Germany
01413 "GH" // Ghana
01414 "GI" // Gibraltar
01415 "GR" // Greece
01416 "GL" // Greenland
01417 "GD" // Grenada
01418 "GP" // Guadeloupe
01419 "GU" // Guam
01420 "GT" // Guatemala
01421 "GN" // Guinea
01422 "GW" // GuineaBissau
01423 "GY" // Guyana
01424 "HT" // Haiti
01425 "HM" // HeardAndMcDonaldIslands
01426 "HN" // Honduras
01427 "HK" // HongKong
01428 "HU" // Hungary
01429 "IS" // Iceland
01430 "IN" // India
01431 "ID" // Indonesia
01432 "IR" // Iran
01433 "IQ" // Iraq
01434 "IE" // Ireland
01435 "IL" // Israel
01436 "IT" // Italy
01437 "JM" // Jamaica
01438 "JP" // Japan
01439 "JO" // Jordan
01440 "KZ" // Kazakhstan
01441 "KE" // Kenya
01442 "KI" // Kiribati
01443 "KP" // DemocraticRepublicOfKorea
01444 "KR" // RepublicOfKorea
01445 "KW" // Kuwait
01446 "KG" // Kyrgyzstan
01447 "LA" // Lao
01448 "LV" // Latvia
01449 "LB" // Lebanon
01450 "LS" // Lesotho
01451 "LR" // Liberia
01452 "LY" // LibyanArabJamahiriya
01453 "LI" // Liechtenstein
01454 "LT" // Lithuania
01455 "LU" // Luxembourg
01456 "MO" // Macau
01457 "MK" // Macedonia
01458 "MG" // Madagascar
01459 "MW" // Malawi
01460 "MY" // Malaysia
01461 "MV" // Maldives
01462 "ML" // Mali
01463 "MT" // Malta
01464 "MH" // MarshallIslands
01465 "MQ" // Martinique
01466 "MR" // Mauritania
01467 "MU" // Mauritius
01468 "YT" // Mayotte
01469 "MX" // Mexico
01470 "FM" // Micronesia
01471 "MD" // Moldova
01472 "MC" // Monaco
01473 "MN" // Mongolia
01474 "MS" // Montserrat
01475 "MA" // Morocco
01476 "MZ" // Mozambique
01477 "MM" // Myanmar
01478 "NA" // Namibia
01479 "NR" // Nauru
01480 "NP" // Nepal
01481 "NL" // Netherlands
01482 "AN" // NetherlandsAntilles
01483 "NC" // NewCaledonia
01484 "NZ" // NewZealand
01485 "NI" // Nicaragua
01486 "NE" // Niger
01487 "NG" // Nigeria
01488 "NU" // Niue
01489 "NF" // NorfolkIsland
01490 "MP" // NorthernMarianaIslands
01491 "NO" // Norway
01492 "OM" // Oman
01493 "PK" // Pakistan
01494 "PW" // Palau
01495 "PS" // PalestinianTerritory
01496 "PA" // Panama
01497 "PG" // PapuaNewGuinea
01498 "PY" // Paraguay
01499 "PE" // Peru
01500 "PH" // Philippines
01501 "PN" // Pitcairn
01502 "PL" // Poland
01503 "PT" // Portugal
01504 "PR" // PuertoRico
01505 "QA" // Qatar
01506 "RE" // Reunion
01507 "RO" // Romania
01508 "RU" // RussianFederation
01509 "RW" // Rwanda
01510 "KN" // SaintKittsAndNevis
01511 "LC" // StLucia
01512 "VC" // StVincentAndTheGrenadines
01513 "WS" // Samoa
01514 "SM" // SanMarino
01515 "ST" // SaoTomeAndPrincipe
01516 "SA" // SaudiArabia
01517 "SN" // Senegal
01518 "SC" // Seychelles
01519 "SL" // SierraLeone
01520 "SG" // Singapore
01521 "SK" // Slovakia
01522 "SI" // Slovenia
01523 "SB" // SolomonIslands
01524 "SO" // Somalia
01525 "ZA" // SouthAfrica
01526 "GS" // SouthGeorgiaAndTheSouthSandwichIslands
01527 "ES" // Spain
01528 "LK" // SriLanka
01529 "SH" // StHelena
01530 "PM" // StPierreAndMiquelon
01531 "SD" // Sudan
01532 "SR" // Suriname
01533 "SJ" // SvalbardAndJanMayenIslands
01534 "SZ" // Swaziland
01535 "SE" // Sweden
01536 "CH" // Switzerland
01537 "SY" // SyrianArabRepublic
01538 "TW" // Taiwan
01539 "TJ" // Tajikistan
01540 "TZ" // Tanzania
01541 "TH" // Thailand
01542 "TG" // Togo
01543 "TK" // Tokelau
01544 "TO" // Tonga
01545 "TT" // TrinidadAndTobago
01546 "TN" // Tunisia
01547 "TR" // Turkey
01548 "TM" // Turkmenistan
01549 "TC" // TurksAndCaicosIslands
01550 "TV" // Tuvalu
01551 "UG" // Uganda
01552 "UA" // Ukraine
01553 "AE" // UnitedArabEmirates
01554 "GB" // UnitedKingdom
01555 "US" // UnitedStates
01556 "UM" // UnitedStatesMinorOutlyingIslands
01557 "UY" // Uruguay
01558 "UZ" // Uzbekistan
01559 "VU" // Vanuatu
01560 "VA" // VaticanCityState
01561 "VE" // Venezuela
01562 "VN" // VietNam
01563 "VG" // BritishVirginIslands
01564 "VI" // USVirginIslands
01565 "WF" // WallisAndFutunaIslands
01566 "EH" // WesternSahara
01567 "YE" // Yemen
01568 "YU" // Yugoslavia
01569 "ZM" // Zambia
01570 "ZW" // Zimbabwe
01571 ;
01572 
01573 static QLocale::Language codeToLanguage(const QString &code)
01574 {
01575     if (code.length() != 2)
01576         return QLocale::C;
01577 
01578     ushort uc1 = code.unicode()[0].unicode();
01579     ushort uc2 = code.unicode()[1].unicode();
01580 
01581     const char *c = language_code_list;
01582     for (; *c != 0; c += 2) {
01583         if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1])
01584             return (QLocale::Language) ((c - language_code_list)/2);
01585     }
01586 
01587     return QLocale::C;
01588 }
01589 
01590 static QLocale::Country codeToCountry(const QString &code)
01591 {
01592     if (code.length() != 2)
01593         return QLocale::AnyCountry;
01594 
01595     ushort uc1 = code.unicode()[0].unicode();
01596     ushort uc2 = code.unicode()[1].unicode();
01597 
01598     const char *c = country_code_list;
01599     for (; *c != 0; c += 2) {
01600         if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1])
01601             return (QLocale::Country) ((c - country_code_list)/2);
01602     }
01603 
01604     return QLocale::AnyCountry;
01605 }
01606 
01607 static QString languageToCode(QLocale::Language language)
01608 {
01609     if (language == QLocale::C)
01610         return "C";
01611 
01612     QString code;
01613     code.setLength(2);
01614     const char *c = language_code_list + 2*(uint)language;
01615     code[0] = c[0];
01616     code[1] = c[1];
01617     return code;
01618 }
01619 
01620 static QString countryToCode(QLocale::Country country)
01621 {
01622     if (country == QLocale::AnyCountry)
01623         return QString::null;
01624 
01625     QString code;
01626     code.setLength(2);
01627     const char *c = country_code_list + 2*(uint)country;
01628     code[0] = c[0];
01629     code[1] = c[1];
01630     return code;
01631 }
01632 
01633 const QLocalePrivate *QLocale::default_d = 0;
01634 
01635 QString QLocalePrivate::infinity() const
01636 {
01637     return QString::fromLatin1("inf");
01638 }
01639 
01640 QString QLocalePrivate::nan() const
01641 {
01642     return QString::fromLatin1("nan");
01643 }
01644 
01645 const char* QLocalePrivate::systemLocaleName()
01646 {
01647     static QCString lang;
01648     lang = getenv( "LANG" );
01649 
01650 #if !defined( QWS ) && defined( Q_OS_MAC )
01651     if ( !lang.isEmpty() )
01652         return lang;
01653 
01654     char mac_ret[255];
01655     if(!LocaleRefGetPartString(NULL, kLocaleLanguageMask | kLocaleRegionMask, 255, mac_ret))
01656         lang = mac_ret;
01657 #endif
01658 
01659 #if defined(Q_WS_WIN)
01660     if ( !lang.isEmpty() )
01661         return lang;
01662 
01663     QT_WA( {
01664         wchar_t out[256];
01665         QString language;
01666         QString sublanguage;
01667         if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME , out, 255 ) )
01668             language = QString::fromUcs2( (ushort*)out );
01669         if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) )
01670             sublanguage = QString::fromUcs2( (ushort*)out ).lower();
01671         lang = language;
01672         if ( sublanguage != language && !sublanguage.isEmpty() )
01673              lang += "_" + sublanguage;
01674     } , {
01675         char out[256];
01676         QString language;
01677         QString sublanguage;
01678         if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, out, 255 ) )
01679             language = QString::fromLocal8Bit( out );
01680         if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) )
01681             sublanguage = QString::fromLocal8Bit( out ).lower();
01682         lang = language;
01683         if ( sublanguage != language && !sublanguage.isEmpty() )
01684             lang += "_" + sublanguage;
01685     } );
01686 #endif
01687     if ( lang.isEmpty() )
01688         lang = "C";
01689 
01690     return lang;
01691 }
01692 
01693 static const QLocalePrivate *findLocale(QLocale::Language language,
01694                                         QLocale::Country country)
01695 {
01696     unsigned language_id = (unsigned)language;
01697     unsigned country_id = (unsigned)country;
01698 
01699     uint idx = locale_index[language_id];
01700 
01701     const QLocalePrivate *d = locale_data + idx;
01702 
01703     if (idx == 0) // default language has no associated country
01704         return d;
01705 
01706     if (country == QLocale::AnyCountry)
01707         return d;
01708 
01709     Q_ASSERT(d->languageId() == language_id);
01710 
01711     while (d->languageId() == language_id
01712                 && d->countryId() != country_id)
01713         ++d;
01714 
01715     if (d->countryId() == country_id
01716             && d->languageId() == language_id)
01717         return d;
01718 
01719     return locale_data + idx;
01720 }
01721 
02259 QLocale::QLocale(const QString &name)
02260 {
02261     Language lang = C;
02262     Country cntry = AnyCountry;
02263 
02264     uint l = name.length();
02265 
02266     do {
02267         if (l < 2)
02268             break;
02269 
02270         const QChar *uc = name.unicode();
02271         if (l > 2
02272                 && uc[2] != '_'
02273                 && uc[2] != '.'
02274                 && uc[2] != '@')
02275             break;
02276 
02277         lang = codeToLanguage(name.mid(0, 2));
02278         if (lang == C)
02279             break;
02280 
02281         if (l == 2 || uc[2] == '.' || uc[2] == '@')
02282             break;
02283 
02284         // we have uc[2] == '_'
02285         if (l < 5)
02286             break;
02287 
02288         if (l > 5 && uc[5] != '.' && uc[5] != '@')
02289             break;
02290 
02291         cntry = codeToCountry(name.mid(3, 2));
02292     } while (false);
02293 
02294     d = findLocale(lang, cntry);
02295 }
02296 
02303 QLocale::QLocale()
02304 {
02305     if (default_d == 0)
02306         default_d = system().d;
02307 
02308     d = default_d;
02309 }
02310 
02330 QLocale::QLocale(Language language, Country country)
02331 {
02332     d = findLocale(language, country);
02333 
02334     // If not found, should default to system
02335     if (d->languageId() == QLocale::C && language != QLocale::C) {
02336         if (default_d == 0)
02337             default_d = system().d;
02338 
02339         d = default_d;
02340     }
02341 }
02342 
02347 QLocale::QLocale(const QLocale &other)
02348 {
02349     d = other.d;
02350 }
02351 
02357 QLocale &QLocale::operator=(const QLocale &other)
02358 {
02359     d = other.d;
02360     return *this;
02361 }
02362 
02378 void QLocale::setDefault(const QLocale &locale)
02379 {
02380     default_d = locale.d;
02381 }
02382 
02388 QLocale::Language QLocale::language() const
02389 {
02390     return (Language)d->languageId();
02391 }
02392 
02398 QLocale::Country QLocale::country() const
02399 {
02400     return (Country)d->countryId();
02401 }
02402 
02412 QString QLocale::name() const
02413 {
02414     Language l = language();
02415 
02416     QString result = languageToCode(l);
02417 
02418     if (l == C)
02419         return result;
02420 
02421     Country c = country();
02422     if (c == AnyCountry)
02423         return result;
02424 
02425     result.append('_');
02426     result.append(countryToCode(c));
02427 
02428     return result;
02429 }
02430 
02435 QString QLocale::languageToString(Language language)
02436 {
02437     if ((uint)language > (uint)QLocale::LastLanguage)
02438         return "Unknown";
02439     return language_name_list + language_name_index[(uint)language];
02440 }
02441 
02446 QString QLocale::countryToString(Country country)
02447 {
02448     if ((uint)country > (uint)QLocale::LastCountry)
02449         return "Unknown";
02450     return country_name_list + country_name_index[(uint)country];
02451 }
02452 
02465 short QLocale::toShort(const QString &s, bool *ok) const
02466 {
02467     Q_LLONG i = toLongLong(s, ok);
02468     if (i < SHRT_MIN || i > SHRT_MAX) {
02469         if (ok != 0)
02470             *ok = false;
02471         return 0;
02472     }
02473     return (short) i;
02474 }
02475 
02488 ushort QLocale::toUShort(const QString &s, bool *ok) const
02489 {
02490     Q_ULLONG i = toULongLong(s, ok);
02491     if (i > USHRT_MAX) {
02492         if (ok != 0)
02493             *ok = false;
02494         return 0;
02495     }
02496     return (ushort) i;
02497 }
02498 
02511 int QLocale::toInt(const QString &s, bool *ok) const
02512 {
02513     Q_LLONG i = toLongLong(s, ok);
02514     if (i < INT_MIN || i > INT_MAX) {
02515         if (ok != 0)
02516             *ok = false;
02517         return 0;
02518     }
02519     return (int) i;
02520 }
02521 
02534 uint QLocale::toUInt(const QString &s, bool *ok) const
02535 {
02536     Q_ULLONG i = toULongLong(s, ok);
02537     if (i > UINT_MAX) {
02538         if (ok != 0)
02539             *ok = false;
02540         return 0;
02541     }
02542     return (uint) i;
02543 }
02544 
02557 Q_LONG QLocale::toLong(const QString &s, bool *ok) const
02558 {
02559     Q_LLONG i = toLongLong(s, ok);
02560     if (i < LONG_MIN || i > LONG_MAX) {
02561         if (ok != 0)
02562             *ok = false;
02563         return 0;
02564     }
02565     return (Q_LONG) i;
02566 }
02567 
02580 Q_ULONG QLocale::toULong(const QString &s, bool *ok) const
02581 {
02582     Q_ULLONG i = toULongLong(s, ok);
02583     if (i > ULONG_MAX) {
02584         if (ok != 0)
02585             *ok = false;
02586         return 0;
02587     }
02588     return (Q_ULONG) i;
02589 }
02590 
02604 Q_LLONG QLocale::toLongLong(const QString &s, bool *ok) const
02605 {
02606     return d->stringToLongLong(s, 0, ok, QLocalePrivate::ParseGroupSeparators);
02607 }
02608 
02622 Q_ULLONG QLocale::toULongLong(const QString &s, bool *ok) const
02623 {
02624     return d->stringToUnsLongLong(s, 0, ok, QLocalePrivate::ParseGroupSeparators);
02625 }
02626 
02639 float QLocale::toFloat(const QString &s, bool *ok) const
02640 {
02641     return (float) toDouble(s, ok);
02642 }
02643 
02680 double QLocale::toDouble(const QString &s, bool *ok) const
02681 {
02682     return d->stringToDouble(s, ok, QLocalePrivate::ParseGroupSeparators);
02683 }
02684 
02691 QString QLocale::toString(Q_LLONG i) const
02692 {
02693     return d->longLongToString(i, -1, 10, QLocalePrivate::ThousandsGroup);
02694 }
02695 
02702 QString QLocale::toString(Q_ULLONG i) const
02703 {
02704     return d->unsLongLongToString(i, -1, 10, QLocalePrivate::ThousandsGroup);
02705 }
02706 
02707 static bool qIsUpper(char c)
02708 {
02709     return c >= 'A' && c <= 'Z';
02710 }
02711 
02712 static char qToLower(char c)
02713 {
02714     if (c >= 'A' && c <= 'Z')
02715         return c - 'A' + 'a';
02716     else
02717         return c;
02718 }
02719 
02728 QString QLocale::toString(double i, char f, int prec) const
02729 {
02730     QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
02731     uint flags = 0;
02732 
02733     if (qIsUpper(f))
02734         flags = QLocalePrivate::CapitalEorX;
02735     f = qToLower(f);
02736 
02737     switch (f) {
02738         case 'f':
02739             form = QLocalePrivate::DFDecimal;
02740             break;
02741         case 'e':
02742             form = QLocalePrivate::DFExponent;
02743             break;
02744         case 'g':
02745             form = QLocalePrivate::DFSignificantDigits;
02746             break;
02747         default:
02748             break;
02749     }
02750 
02751     flags |= QLocalePrivate::ThousandsGroup;
02752     return d->doubleToString(i, prec, form, -1, flags);
02753 }
02754 
02767 QLocale QLocale::system()
02768 {
02769 #ifdef Q_OS_UNIX
02770     const char *s = getenv("LC_NUMERIC");
02771     if (s == 0)
02772         s = getenv("LC_ALL");
02773     if (s != 0)
02774         return QLocale(s);
02775 #endif
02776     return QLocale(QLocalePrivate::systemLocaleName());
02777 }
02778 
02838 bool QLocalePrivate::isDigit(QChar d) const
02839 {
02840     return zero().unicode() <= d.unicode()
02841             && zero().unicode() + 10 > d.unicode();
02842 }
02843 
02844 static char digitToCLocale(QChar zero, QChar d)
02845 {
02846     if (zero.unicode() <= d.unicode()
02847             && zero.unicode() + 10 > d.unicode())
02848         return '0' + d.unicode() - zero.unicode();
02849 
02850     qWarning("QLocalePrivate::digitToCLocale(): bad digit: row=%d, cell=%d", d.row(), d.cell());
02851     return QChar(0);
02852 }
02853 
02854 static QString qulltoa(Q_ULLONG l, int base, const QLocalePrivate &locale)
02855 {
02856     QChar buff[65]; // length of MAX_ULLONG in base 2
02857     QChar *p = buff + 65;
02858 
02859     if (base != 10 || locale.zero().unicode() == '0') {
02860         while (l != 0) {
02861             int c = l % base;
02862 
02863             --p;
02864 
02865             if (c < 10)
02866                 *p = '0' + c;
02867             else
02868                 *p = c - 10 + 'a';
02869 
02870             l /= base;
02871         }
02872     }
02873     else {
02874         while (l != 0) {
02875             int c = l % base;
02876 
02877             *(--p) = locale.zero().unicode() + c;
02878 
02879             l /= base;
02880         }
02881     }
02882 
02883     return QString(p, 65 - (p - buff));
02884 }
02885 
02886 static QString qlltoa(Q_LLONG l, int base, const QLocalePrivate &locale)
02887 {
02888     return qulltoa(l < 0 ? -l : l, base, locale);
02889 }
02890 
02891 enum PrecisionMode {
02892     PMDecimalDigits =       0x01,
02893     PMSignificantDigits =   0x02,
02894     PMChopTrailingZeros =   0x03
02895 };
02896 
02897 static QString &decimalForm(QString &digits, int decpt, uint precision,
02898                             PrecisionMode pm,
02899                             bool always_show_decpt,
02900                             bool thousands_group,
02901                             const QLocalePrivate &locale)
02902 {
02903     if (decpt < 0) {
02904         for (int i = 0; i < -decpt; ++i)
02905             digits.prepend(locale.zero());
02906         decpt = 0;
02907     }
02908     else if ((uint)decpt > digits.length()) {
02909         for (uint i = digits.length(); i < (uint)decpt; ++i)
02910             digits.append(locale.zero());
02911     }
02912 
02913     if (pm == PMDecimalDigits) {
02914         uint decimal_digits = digits.length() - decpt;
02915         for (uint i = decimal_digits; i < precision; ++i)
02916             digits.append(locale.zero());
02917     }
02918     else if (pm == PMSignificantDigits) {
02919         for (uint i = digits.length(); i < precision; ++i)
02920             digits.append(locale.zero());
02921     }
02922     else { // pm == PMChopTrailingZeros
02923     }
02924 
02925     if (always_show_decpt || (uint)decpt < digits.length())
02926         digits.insert(decpt, locale.decimal());
02927 
02928     if (thousands_group) {
02929         for (int i = decpt - 3; i > 0; i -= 3)
02930             digits.insert(i, locale.group());
02931     }
02932 
02933     if (decpt == 0)
02934         digits.prepend(locale.zero());
02935 
02936     return digits;
02937 }
02938 
02939 static QString &exponentForm(QString &digits, int decpt, uint precision,
02940                                 PrecisionMode pm,
02941                                 bool always_show_decpt,
02942                                 const QLocalePrivate &locale)
02943 {
02944     int exp = decpt - 1;
02945 
02946     if (pm == PMDecimalDigits) {
02947         for (uint i = digits.length(); i < precision + 1; ++i)
02948             digits.append(locale.zero());
02949     }
02950     else if (pm == PMSignificantDigits) {
02951         for (uint i = digits.length(); i < precision; ++i)
02952             digits.append(locale.zero());
02953     }
02954     else { // pm == PMChopTrailingZeros
02955     }
02956 
02957     if (always_show_decpt || digits.length() > 1)
02958         digits.insert(1, locale.decimal());
02959 
02960     digits.append(locale.exponential());
02961     digits.append(locale.longLongToString(exp, 2, 10,
02962                             -1, QLocalePrivate::AlwaysShowSign));
02963 
02964     return digits;
02965 }
02966 
02967 QString QLocalePrivate::doubleToString(double d,
02968             int precision,
02969             DoubleForm form,
02970             int width,
02971             unsigned flags) const
02972 {
02973     if (precision == -1)
02974         precision = 6;
02975     if (width == -1)
02976         width = 0;
02977 
02978     bool negative = false;
02979     bool special_number = false; // nan, +/-inf
02980     QString num_str;
02981 
02982     // Comparing directly to INFINITY gives weird results on some systems.
02983     double tmp_infinity = INFINITY;
02984 
02985     // Detect special numbers (nan, +/-inf)
02986     if (d == tmp_infinity || d == -tmp_infinity) {
02987         num_str = infinity();
02988         special_number = true;
02989         negative = d < 0;
02990     } else if (isnan(d)) {
02991         num_str = nan();
02992         special_number = true;
02993     }
02994 
02995     // Handle normal numbers
02996     if (!special_number) {
02997         int decpt, sign;
02998         QString digits;
02999 
03000 #ifdef QT_QLOCALE_USES_FCVT
03001 #ifdef QT_THREAD_SUPPORT
03002         static bool dummy_for_mutex;
03003         QMutex *fcvt_mutex =  qt_global_mutexpool ? qt_global_mutexpool->get( &dummy_for_mutex ) : 0;
03004 # define FCVT_LOCK if (fcvt_mutex) fcvt_mutex->lock()
03005 # define FCVT_UNLOCK if (fcvt_mutex) fcvt_mutex->unlock()
03006 #else
03007 # define FCVT_LOCK
03008 # define FCVT_UNLOCK
03009 #endif
03010         if (form == DFDecimal) {
03011             FCVT_LOCK;
03012             digits = fcvt(d, precision, &decpt, &sign);
03013             FCVT_UNLOCK;
03014         } else {
03015             int pr = precision;
03016             if (form == DFExponent)
03017                 ++pr;
03018             else if (form == DFSignificantDigits && pr == 0)
03019                 pr = 1;
03020             FCVT_LOCK;
03021             digits = ecvt(d, pr, &decpt, &sign);
03022             FCVT_UNLOCK;
03023 
03024             // Chop trailing zeros
03025             if (digits.length() > 0) {
03026                 int last_nonzero_idx = digits.length() - 1;
03027                 while (last_nonzero_idx > 0
03028                        && digits.unicode()[last_nonzero_idx] == '0')
03029                     --last_nonzero_idx;
03030                 digits.truncate(last_nonzero_idx + 1);
03031             }
03032 
03033         }
03034 
03035 #else
03036         int mode;
03037         if (form == DFDecimal)
03038             mode = 3;
03039         else
03040             mode = 2;
03041 
03042         /* This next bit is a bit quirky. In DFExponent form, the precision
03043            is the number of digits after decpt. So that would suggest using
03044            mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and
03045            precision=0. So we get around this by using mode=2 and reasoning
03046            that we want precision+1 significant digits, since the decimal
03047            point in this mode is always after the first digit. */
03048         int pr = precision;
03049         if (form == DFExponent)
03050             ++pr;
03051 
03052         char *rve = 0;
03053         char *buff = 0;
03054         digits = qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff);
03055         if (buff != 0)
03056             free(buff);
03057 #endif // QT_QLOCALE_USES_FCVT
03058 
03059         if (zero().unicode() != '0') {
03060             for (uint i = 0; i < digits.length(); ++i)
03061                 digits.ref(i).unicode() += zero().unicode() - '0';
03062         }
03063 
03064         bool always_show_decpt = flags & Alternate;
03065         switch (form) {
03066             case DFExponent: {
03067                 num_str = exponentForm(digits, decpt, precision, PMDecimalDigits,
03068                                         always_show_decpt, *this);
03069                 break;
03070             }
03071             case DFDecimal: {
03072                 num_str = decimalForm(digits, decpt, precision, PMDecimalDigits,
03073                                         always_show_decpt, flags & ThousandsGroup,
03074                                         *this);
03075                 break;
03076             }
03077             case DFSignificantDigits: {
03078                 PrecisionMode mode = (flags & Alternate) ?
03079                             PMSignificantDigits : PMChopTrailingZeros;
03080 
03081                 if (decpt != (int)digits.length() && (decpt <= -4 || decpt > (int)precision))
03082                     num_str = exponentForm(digits, decpt, precision, mode,
03083                                             always_show_decpt, *this);
03084                 else
03085                     num_str = decimalForm(digits, decpt, precision, mode,
03086                                             always_show_decpt, flags & ThousandsGroup,
03087                                             *this);
03088                 break;
03089             }
03090         }
03091 
03092         negative = sign != 0;
03093     }
03094 
03095     // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
03096     // pad special numbers
03097     if (flags & QLocalePrivate::ZeroPadded
03098             && !(flags & QLocalePrivate::LeftAdjusted)
03099             && !special_number) {
03100         int num_pad_chars = width - (int)num_str.length();
03101         // leave space for the sign
03102         if (negative
03103                 || flags & QLocalePrivate::AlwaysShowSign
03104                 || flags & QLocalePrivate::BlankBeforePositive)
03105             --num_pad_chars;
03106 
03107         for (int i = 0; i < num_pad_chars; ++i)
03108             num_str.prepend(zero());
03109     }
03110 
03111     // add sign
03112     if (negative)
03113         num_str.prepend(minus());
03114     else if (flags & QLocalePrivate::AlwaysShowSign)
03115         num_str.prepend(plus());
03116     else if (flags & QLocalePrivate::BlankBeforePositive)
03117         num_str.prepend(' ');
03118 
03119     if (flags & QLocalePrivate::CapitalEorX)
03120         num_str = num_str.upper();
03121 
03122     return num_str;
03123 }
03124 
03125 QString QLocalePrivate::longLongToString(Q_LLONG l, int precision,
03126                                 int base, int width,
03127                                 unsigned flags) const
03128 {
03129     bool precision_not_specified = false;
03130     if (precision == -1) {
03131         precision_not_specified = true;
03132         precision = 1;
03133     }
03134 
03135     bool negative = l < 0;
03136     if (base != 10) {
03137         // these are not suported by sprintf for octal and hex
03138         flags &= ~AlwaysShowSign;
03139         flags &= ~BlankBeforePositive;
03140         negative = false; // neither are negative numbers
03141     }
03142 
03143     QString num_str;
03144     if (base == 10)
03145         num_str = qlltoa(l, base, *this);
03146     else
03147         num_str = qulltoa(l, base, *this);
03148 
03149     uint cnt_thousand_sep = 0;
03150     if (flags & ThousandsGroup && base == 10) {
03151         for (int i = (int)num_str.length() - 3; i > 0; i -= 3) {
03152             num_str.insert(i, group());
03153             ++cnt_thousand_sep;
03154         }
03155     }
03156 
03157     for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
03158         num_str.prepend(base == 10 ? zero() : QChar('0'));
03159 
03160     if (flags & Alternate
03161             && base == 8
03162             && (num_str.isEmpty()
03163                     || num_str[0].unicode() != '0'))
03164         num_str.prepend('0');
03165 
03166     // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
03167     // when precision is not specified in the format string
03168     bool zero_padded = flags & ZeroPadded
03169                         && !(flags & LeftAdjusted)
03170                         && precision_not_specified;
03171 
03172     if (zero_padded) {
03173         int num_pad_chars = width - (int)num_str.length();
03174 
03175         // leave space for the sign
03176         if (negative
03177                 || flags & AlwaysShowSign
03178                 || flags & BlankBeforePositive)
03179             --num_pad_chars;
03180 
03181         // leave space for optional '0x' in hex form
03182         if (base == 16
03183                 && flags & Alternate
03184                 && l != 0)
03185             num_pad_chars -= 2;
03186 
03187         for (int i = 0; i < num_pad_chars; ++i)
03188             num_str.prepend(base == 10 ? zero() : QChar('0'));
03189     }
03190 
03191     if (base == 16
03192             && flags & Alternate
03193             && l != 0)
03194         num_str.prepend("0x");
03195 
03196     // add sign
03197     if (negative)
03198         num_str.prepend(minus());
03199     else if (flags & AlwaysShowSign)
03200         num_str.prepend(base == 10 ? plus() : QChar('+'));
03201     else if (flags & BlankBeforePositive)
03202         num_str.prepend(' ');
03203 
03204     if (flags & CapitalEorX)
03205         num_str = num_str.upper();
03206 
03207     return num_str;
03208 }
03209 
03210 QString QLocalePrivate::unsLongLongToString(Q_ULLONG l, int precision,
03211                                 int base, int width,
03212                                 unsigned flags) const
03213 {
03214     bool precision_not_specified = false;
03215     if (precision == -1) {
03216         precision_not_specified = true;
03217         precision = 1;
03218     }
03219 
03220     QString num_str = qulltoa(l, base, *this);
03221 
03222     uint cnt_thousand_sep = 0;
03223     if (flags & ThousandsGroup && base == 10) {
03224         for (int i = (int)num_str.length() - 3; i > 0; i -=3) {
03225             num_str.insert(i, group());
03226             ++cnt_thousand_sep;
03227         }
03228     }
03229 
03230     for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
03231         num_str.prepend(base == 10 ? zero() : QChar('0'));
03232 
03233     if (flags & Alternate
03234             && base == 8
03235             && (num_str.isEmpty()
03236                     || num_str[0].unicode() != '0'))
03237         num_str.prepend('0');
03238 
03239     // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
03240     // when precision is not specified in the format string
03241     bool zero_padded = flags & ZeroPadded
03242                         && !(flags & LeftAdjusted)
03243                         && precision_not_specified;
03244 
03245     if (zero_padded) {
03246         int num_pad_chars = width - (int)num_str.length();
03247 
03248         // leave space for optional '0x' in hex form
03249         if (base == 16
03250                 && flags & Alternate
03251                 && l != 0)
03252             num_pad_chars -= 2;
03253 
03254         for (int i = 0; i < num_pad_chars; ++i)
03255             num_str.prepend(base == 10 ? zero() : QChar('0'));
03256     }
03257 
03258     if (base == 16
03259             && flags & Alternate
03260             && l != 0)
03261         num_str.prepend("0x");
03262 
03263     if (flags & CapitalEorX)
03264         num_str = num_str.upper();
03265 
03266     return num_str;
03267 }
03268 
03269 static bool compareSubstr(const QString &s1, uint idx, const QString &s2)
03270 {
03271     uint i = 0;
03272     for (; i + idx < s1.length() && i < s2.length(); ++i) {
03273         if (s1.unicode()[i + idx] != s2.unicode()[i])
03274             return false;
03275     }
03276 
03277     return i == s2.length();
03278 }
03279 
03280 // Removes thousand-group separators, ie. the ',' in "1,234,567.89e-5"
03281 bool QLocalePrivate::removeGroupSeparators(QString &num_str) const
03282 {
03283     int group_cnt = 0; // counts number of group chars
03284     int decpt_idx = -1;
03285 
03286     // Find the decimal point and check if there are any group chars
03287     uint i = 0;
03288     for (; i < num_str.length(); ++i) {
03289         QChar c = num_str.unicode()[i];
03290 
03291         if (c == group()) {
03292             // check that there are digits before and after the separator
03293             if (i == 0 || !isDigit(num_str.unicode()[i - 1]))
03294                 return false;
03295             if (i == num_str.length() + 1 || !isDigit(num_str.unicode()[i + 1]))
03296                 return false;
03297             ++group_cnt;
03298         }
03299         else if (c == decimal()) {
03300             // Fail if more than one decimal points
03301             if (decpt_idx != -1)
03302                 return false;
03303             decpt_idx = i;
03304         } else if (c == exponential() || c == exponential().upper()) {
03305             // an 'e' or 'E' - if we have not encountered a decimal
03306             // point, this is where it "is".
03307             if (decpt_idx == -1)
03308                 decpt_idx = i;
03309         }
03310     }
03311 
03312     // If no group chars, we're done
03313     if (group_cnt == 0)
03314         return true;
03315 
03316     // No decimal point means that it "is" at the end of the string
03317     if (decpt_idx == -1)
03318         decpt_idx = num_str.length();
03319 
03320     i = 0;
03321     while (i < num_str.length() && group_cnt > 0) {
03322         QChar c = num_str.unicode()[i];
03323 
03324         if (c == group()) {
03325             // Don't allow group chars after the decimal point
03326             if ((int)i > decpt_idx)
03327                 return false;
03328 
03329             // Check that it is placed correctly relative to the decpt
03330             if ((decpt_idx - i) % 4 != 0)
03331                 return false;
03332 
03333             // Remove it
03334             num_str.remove(i, 1);
03335 
03336             --group_cnt;
03337             --decpt_idx; // adjust decpt_idx
03338         } else {
03339             // Check that we are not missing a separator
03340             if ((int)i < decpt_idx && (decpt_idx - i) % 4 == 0)
03341                 return false;
03342             ++i;
03343         }
03344     }
03345 
03346     return true;
03347 }
03348 
03349 static void stripWhiteSpaceInPlace(QString &s)
03350 {
03351     uint i = 0;
03352     while (i < s.length() && s.unicode()[i].isSpace())
03353         ++i;
03354     if (i > 0)
03355         s.remove(0, i);
03356 
03357     i = s.length();
03358 
03359     if (i == 0)
03360         return;
03361     --i;
03362     while (i > 0 && s.unicode()[i].isSpace())
03363         --i;
03364     if (i + 1 < s.length())
03365         s.truncate(i + 1);
03366 }
03367 
03368 // Converts a number in locale to its representation in the C locale.
03369 bool QLocalePrivate::numberToCLocale(QString &l_num,
03370                                         GroupSeparatorMode group_sep_mode) const
03371 {
03372     stripWhiteSpaceInPlace(l_num);
03373 
03374     if (group_sep_mode == ParseGroupSeparators
03375             && !removeGroupSeparators(l_num))
03376         return false;
03377 
03378     uint idx = 0;
03379     if (compareSubstr(l_num, idx, nan())) {
03380         idx += nan().length();
03381         return idx == l_num.length();
03382     }
03383     else if (compareSubstr(l_num, idx, nan().upper())) {
03384         for (uint i = idx; i < idx + nan().length(); ++i)
03385             l_num.ref(i) = l_num.unicode()[i].lower();
03386         idx += nan().length();
03387         return idx == l_num.length();
03388     }
03389     QChar &c = l_num.ref(idx);
03390 
03391     if (c == plus()) {
03392         c.unicode() = '+';
03393         ++idx;
03394     }
03395     else if (c == minus()) {
03396         c.unicode() = '-';
03397         ++idx;
03398     }
03399 
03400     if (compareSubstr(l_num, idx, infinity())) {
03401         idx += infinity().length();
03402         return idx == l_num.length();
03403     }
03404     else if (compareSubstr(l_num, idx, infinity().upper())) {
03405         for (uint i = idx; i < idx + infinity().length(); ++i)
03406             l_num.ref(i) = l_num.unicode()[i].lower();
03407         idx += infinity().length();
03408         return idx == l_num.length();
03409     }
03410 
03411     while (idx < l_num.length()) {
03412         QChar &c = l_num.ref(idx);
03413 
03414         if (isDigit(c))
03415             c = digitToCLocale(zero(), c);
03416         else if (c == plus())
03417             c = '+';
03418         else if (c == minus())
03419             c = '-';
03420         else if (c == decimal())
03421             c = '.';
03422         else if (c == group())
03423             c = ',';
03424         else if (c == exponential() || c == exponential().upper())
03425             c = 'e';
03426         else if (c.unicode() == 'x' || c.unicode() == 'X') // hex number
03427             c = 'x';
03428         else if (c == list())
03429             c = ';';
03430         else if (c == percent())
03431             c = '%';
03432         else if (c.unicode() >= 'A' && c.unicode() <= 'F')
03433             c = c.upper();
03434         else if (c.unicode() >= 'a' && c.unicode() <= 'f')
03435             ; // do nothing
03436         else
03437             return false;
03438 
03439         ++idx;
03440     }
03441 
03442     return true;
03443 }
03444 
03445 double QLocalePrivate::stringToDouble(QString num,
03446                                         bool *ok,
03447                                         GroupSeparatorMode group_sep_mode) const
03448 {
03449     if (!numberToCLocale(num, group_sep_mode)) {
03450         if (ok != 0)
03451             *ok = false;
03452         return 0.0;
03453     }
03454 
03455     if (ok != 0)
03456         *ok = true;
03457 
03458     if (num == "nan")
03459         return NAN;
03460 
03461     if (num == "+inf"
03462             || num == "inf")
03463         return INFINITY;
03464 
03465     if (num == "-inf")
03466         return -INFINITY;
03467 
03468     bool _ok;
03469     const char *num_buff = num.latin1();
03470 
03471 #ifdef QT_QLOCALE_USES_FCVT
03472     char *endptr;
03473     double d = strtod(num_buff, &endptr);
03474     _ok = true;
03475 #else
03476     const char *endptr;
03477     double d = qstrtod(num_buff, &endptr, &_ok);
03478 #endif
03479 
03480     if (!_ok || *endptr != '\0') {
03481         if (ok != 0)
03482             *ok = false;
03483         return 0.0;
03484     }
03485     else
03486         return d;
03487 }
03488 
03489 Q_LLONG QLocalePrivate::stringToLongLong(QString num, int base,
03490                                     bool *ok,
03491                                     GroupSeparatorMode group_sep_mode) const
03492 {
03493     if (!numberToCLocale(num, group_sep_mode)) {
03494         if (ok != 0)
03495             *ok = false;
03496         return 0;
03497     }
03498 
03499     bool _ok;
03500     const char *endptr;
03501     const char *num_buff = num.latin1();
03502     Q_LLONG l = qstrtoll(num_buff, &endptr, base, &_ok);
03503 
03504     if (!_ok || *endptr != '\0') {
03505         if (ok != 0)
03506             *ok = false;
03507         return 0;
03508     }
03509 
03510     if (ok != 0)
03511         *ok = true;
03512     return l;
03513 }
03514 
03515 Q_ULLONG QLocalePrivate::stringToUnsLongLong(QString num, int base,
03516                                     bool *ok,
03517                                     GroupSeparatorMode group_sep_mode) const
03518 {
03519     if (!numberToCLocale(num, group_sep_mode)) {
03520         if (ok != 0)
03521             *ok = false;
03522         return 0;
03523     }
03524 
03525     bool _ok;
03526     const char *endptr;
03527     const char *num_buff = num.latin1();
03528     Q_ULLONG l = qstrtoull(num_buff, &endptr, base, &_ok);
03529 
03530     if (!_ok || *endptr != '\0') {
03531         if (ok != 0)
03532             *ok = false;
03533         return 0;
03534     }
03535 
03536     if (ok != 0)
03537         *ok = true;
03538     return l;
03539 }
03540 
03541 /*-
03542  * Copyright (c) 1992, 1993
03543  *      The Regents of the University of California.  All rights reserved.
03544  *
03545  * Redistribution and use in source and binary forms, with or without
03546  * modification, are permitted provided that the following conditions
03547  * are met:
03548  * 1. Redistributions of source code must retain the above copyright
03549  *    notice, this list of conditions and the following disclaimer.
03550  * 2. Redistributions in binary form must reproduce the above copyright
03551  *    notice, this list of conditions and the following disclaimer in the
03552  *    documentation and/or other materials provided with the distribution.
03553  * 3. All advertising materials mentioning features or use of this software
03554  *    must display the following acknowledgement:
03555  *      This product includes software developed by the University of
03556  *      California, Berkeley and its contributors.
03557  * 4. Neither the name of the University nor the names of its contributors
03558  *    may be used to endorse or promote products derived from this software
03559  *    without specific prior written permission.
03560  *
03561  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
03562  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
03563  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
03564  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
03565  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
03566  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
03567  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
03568  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
03569  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
03570  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
03571  * SUCH DAMAGE.
03572  */
03573 
03574 // static char sccsid[] = "@(#)strtouq.c        8.1 (Berkeley) 6/4/93";
03575 //  "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
03576 
03577 /*
03578  * Convert a string to an Q_ULLONG integer.
03579  *
03580  * Ignores `locale' stuff.  Assumes that the upper and lower case
03581  * alphabets and digits are each contiguous.
03582  */
03583 static Q_ULLONG qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok)
03584 {
03585     register const char *s = nptr;
03586     register Q_ULLONG acc;
03587     register unsigned char c;
03588     register Q_ULLONG qbase, cutoff;
03589     register int neg, any, cutlim;
03590 
03591     if (ok != 0)
03592         *ok = true;
03593 
03594     /*
03595      * See strtoq for comments as to the logic used.
03596      */
03597     s = nptr;
03598     do {
03599         c = *s++;
03600     } while (isspace(c));
03601     if (c == '-') {
03602         if (ok != 0)
03603             *ok = false;
03604         if (endptr != 0)
03605             *endptr = s - 1;
03606         return 0;
03607     } else {
03608         neg = 0;
03609         if (c == '+')
03610             c = *s++;
03611     }
03612     if ((base == 0 || base == 16) &&
03613         c == '0' && (*s == 'x' || *s == 'X')) {
03614         c = s[1];
03615         s += 2;
03616         base = 16;
03617     }
03618     if (base == 0)
03619         base = c == '0' ? 8 : 10;
03620     qbase = (unsigned)base;
03621     cutoff = (Q_ULLONG)ULLONG_MAX / qbase;
03622     cutlim = (Q_ULLONG)ULLONG_MAX % qbase;
03623     for (acc = 0, any = 0;; c = *s++) {
03624         if (!isascii(c))
03625             break;
03626         if (isdigit(c))
03627             c -= '0';
03628         else if (isalpha(c))
03629             c -= isupper(c) ? 'A' - 10 : 'a' - 10;
03630         else
03631             break;
03632         if (c >= base)
03633             break;
03634         if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
03635             any = -1;
03636         else {
03637             any = 1;
03638             acc *= qbase;
03639             acc += c;
03640         }
03641     }
03642     if (any < 0) {
03643         acc = ULLONG_MAX;
03644         if (ok != 0)
03645             *ok = false;
03646     }
03647     else if (neg)
03648         acc = (~acc) + 1;
03649     if (endptr != 0)
03650         *endptr = (char *)(any ? s - 1 : nptr);
03651     return (acc);
03652 }
03653 
03654 
03655 //  "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
03656 
03657 
03658 /*
03659  * Convert a string to a Q_LLONG integer.
03660  *
03661  * Ignores `locale' stuff.  Assumes that the upper and lower case
03662  * alphabets and digits are each contiguous.
03663  */
03664 static Q_LLONG qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok)
03665 {
03666     register const char *s;
03667     register Q_ULLONG acc;
03668     register unsigned char c;
03669     register Q_ULLONG qbase, cutoff;
03670     register int neg, any, cutlim;
03671 
03672     if (ok != 0)
03673         *ok = true;
03674 
03675     /*
03676      * Skip white space and pick up leading +/- sign if any.
03677      * If base is 0, allow 0x for hex and 0 for octal, else
03678      * assume decimal; if base is already 16, allow 0x.
03679      */
03680     s = nptr;
03681     do {
03682         c = *s++;
03683     } while (isspace(c));
03684     if (c == '-') {
03685         neg = 1;
03686         c = *s++;
03687     } else {
03688         neg = 0;
03689         if (c == '+')
03690             c = *s++;
03691     }
03692     if ((base == 0 || base == 16) &&
03693         c == '0' && (*s == 'x' || *s == 'X')) {
03694         c = s[1];
03695         s += 2;
03696         base = 16;
03697     }
03698     if (base == 0)
03699         base = c == '0' ? 8 : 10;
03700 
03701     /*
03702      * Compute the cutoff value between legal numbers and illegal
03703      * numbers.  That is the largest legal value, divided by the
03704      * base.  An input number that is greater than this value, if
03705      * followed by a legal input character, is too big.  One that
03706      * is equal to this value may be valid or not; the limit
03707      * between valid and invalid numbers is then based on the last
03708      * digit.  For instance, if the range for quads is
03709      * [-9223372036854775808..9223372036854775807] and the input base
03710      * is 10, cutoff will be set to 922337203685477580 and cutlim to
03711      * either 7 (neg==0) or 8 (neg==1), meaning that if we have
03712      * accumulated a value > 922337203685477580, or equal but the
03713      * next digit is > 7 (or 8), the number is too big, and we will
03714      * return a range error.
03715      *
03716      * Set any if any `digits' consumed; make it negative to indicate
03717      * overflow.
03718      */
03719     qbase = (unsigned)base;
03720     cutoff = neg ? (Q_ULLONG)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX
03721         : LLONG_MAX;
03722     cutlim = cutoff % qbase;
03723     cutoff /= qbase;
03724     for (acc = 0, any = 0;; c = *s++) {
03725         if (!isascii(c))
03726             break;
03727         if (isdigit(c))
03728             c -= '0';
03729         else if (isalpha(c))
03730             c -= isupper(c) ? 'A' - 10 : 'a' - 10;
03731         else
03732             break;
03733         if (c >= base)
03734             break;
03735         if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
03736             any = -1;
03737         else {
03738             any = 1;
03739             acc *= qbase;
03740             acc += c;
03741         }
03742     }
03743     if (any < 0) {
03744         acc = neg ? LLONG_MIN : LLONG_MAX;
03745         if (ok != 0)
03746             *ok = false;
03747     } else if (neg) {
03748         acc = (~acc) + 1;
03749     }
03750     if (endptr != 0)
03751         *endptr = (char *)(any ? s - 1 : nptr);
03752     return (acc);
03753 }
03754 
03755 #ifndef QT_QLOCALE_USES_FCVT
03756 
03757 /*      From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */
03758 /* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $      */
03759 
03760 /* Please send bug reports to
03761         David M. Gay
03762         AT&T Bell Laboratories, Room 2C-463
03763         600 Mountain Avenue
03764         Murray Hill, NJ 07974-2070
03765         U.S.A.
03766         dmg@research.att.com or research!dmg
03767  */
03768 
03769 /* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
03770  *
03771  * This strtod returns a nearest machine number to the input decimal
03772  * string (or sets errno to ERANGE).  With IEEE arithmetic, ties are
03773  * broken by the IEEE round-even rule.  Otherwise ties are broken by
03774  * biased rounding (add half and chop).
03775  *
03776  * Inspired loosely by William D. Clinger's paper "How to Read Floating
03777  * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
03778  *
03779  * Modifications:
03780  *
03781  *      1. We only require IEEE, IBM, or VAX double-precision
03782  *              arithmetic (not IEEE double-extended).
03783  *      2. We get by with floating-point arithmetic in a case that
03784  *              Clinger missed -- when we're computing d * 10^n
03785  *              for a small integer d and the integer n is not too
03786  *              much larger than 22 (the maximum integer k for which
03787  *              we can represent 10^k exactly), we may be able to
03788  *              compute (d*10^k) * 10^(e-k) with just one roundoff.
03789  *      3. Rather than a bit-at-a-time adjustment of the binary
03790  *              result in the hard case, we use floating-point
03791  *              arithmetic to determine the adjustment to within
03792  *              one bit; only in really hard cases do we need to
03793  *              compute a second residual.
03794  *      4. Because of 3., we don't need a large table of powers of 10
03795  *              for ten-to-e (just some small tables, e.g. of 10^k
03796  *              for 0 <= k <= 22).
03797  */
03798 
03799 /*
03800  * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
03801  *      significant byte has the lowest address.
03802  * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
03803  *      significant byte has the lowest address.
03804  * #define Long int on machines with 32-bit ints and 64-bit longs.
03805  * #define Sudden_Underflow for IEEE-format machines without gradual
03806  *      underflow (i.e., that flush to zero on underflow).
03807  * #define IBM for IBM mainframe-style floating-point arithmetic.
03808  * #define VAX for VAX-style floating-point arithmetic.
03809  * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
03810  * #define No_leftright to omit left-right logic in fast floating-point
03811  *      computation of dtoa.
03812  * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
03813  * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
03814  *      that use extended-precision instructions to compute rounded
03815  *      products and quotients) with IBM.
03816  * #define ROUND_BIASED for IEEE-format with biased rounding.
03817  * #define Inaccurate_Divide for IEEE-format with correctly rounded
03818  *      products but inaccurate quotients, e.g., for Intel i860.
03819  * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
03820  *      integer arithmetic.  Whether this speeds things up or slows things
03821  *      down depends on the machine and the number being converted.
03822  * #define KR_headers for old-style C function headers.
03823  * #define Bad_float_h if your system lacks a float.h or if it does not
03824  *      define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
03825  *      FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
03826  * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
03827  *      if memory is available and otherwise does something you deem
03828  *      appropriate.  If MALLOC is undefined, malloc will be invoked
03829  *      directly -- and assumed always to succeed.
03830  */
03831 
03832 #if defined(LIBC_SCCS) && !defined(lint)
03833 __RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $");
03834 #endif /* LIBC_SCCS and not lint */
03835 
03836 /*
03837 #if defined(__m68k__)    || defined(__sparc__) || defined(__i386__) || \
03838      defined(__mips__)    || defined(__ns32k__) || defined(__alpha__) || \
03839      defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MACX) || \
03840      defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS)
03841 #       define IEEE_BIG_OR_LITTLE_ENDIAN 1
03842 #endif
03843 */
03844 
03845 // *All* of our architectures have IEEE arithmetic, don't they?
03846 #define IEEE_BIG_OR_LITTLE_ENDIAN 1
03847 
03848 #ifdef __arm32__
03849 /*
03850  * Although the CPU is little endian the FP has different
03851  * byte and word endianness. The byte order is still little endian
03852  * but the word order is big endian.
03853  */
03854 #define IEEE_BIG_OR_LITTLE_ENDIAN
03855 #endif
03856 
03857 #ifdef vax
03858 #define VAX
03859 #endif
03860 
03861 #define Long    Q_INT32
03862 #define ULong   Q_UINT32
03863 
03864 #define MALLOC malloc
03865 #define CONST const
03866 
03867 #ifdef BSD_QDTOA_DEBUG
03868 #include <stdio.h>
03869 #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
03870 #endif
03871 
03872 #ifdef Unsigned_Shifts
03873 #define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
03874 #else
03875 #define Sign_Extend(a,b) /*no-op*/
03876 #endif
03877 
03878 #if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1
03879 #error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined.
03880 #endif
03881 
03882 
03883 #define word0(x) ((volatile ULong *)&x)[ByteOrder == BigEndian ? 0 : 1]
03884 #define word1(x) ((volatile ULong *)&x)[ByteOrder == BigEndian ? 1 : 0]
03885 
03886 
03887 /* The following definition of Storeinc is appropriate for MIPS processors.
03888  * An alternative that might be better on some machines is
03889  * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
03890  */
03891 
03892 /*
03893 #if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
03894 #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
03895 ((unsigned short *)a)[0] = (unsigned short)c, a++)
03896 #else
03897 #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
03898 ((unsigned short *)a)[1] = (unsigned short)c, a++)
03899 #endif
03900 */
03901 
03902 static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c)
03903 {
03904 
03905 #   if defined(VAX) + defined(__arm32__)
03906 #       define USE_LITTLE_ENDIAN 1
03907 #   else
03908 #       define USE_LITTLE_ENDIAN 0
03909 #   endif
03910 
03911 #   if defined(IEEE_BIG_OR_LITTLE_ENDIAN)
03912 #       define USE_IEEE 1
03913 #   else
03914 #       define USE_IEEE 0
03915 #   endif
03916 
03917     if (ByteOrder == LittleEndian && USE_IEEE || USE_LITTLE_ENDIAN) {
03918         ((unsigned short *)a)[1] = (unsigned short)b;
03919         ((unsigned short *)a)[0] = (unsigned short)c;
03920     } else {
03921         ((unsigned short *)a)[0] = (unsigned short)b;
03922         ((unsigned short *)a)[1] = (unsigned short)c;
03923     }
03924 
03925     ++a;
03926 
03927 #   undef USE_LITTLE_ENDIAN
03928 #   undef USE_IEEE
03929 }
03930 
03931 /* #define P DBL_MANT_DIG */
03932 /* Ten_pmax = floor(P*log(2)/log(5)) */
03933 /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
03934 /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
03935 /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
03936 
03937 #if defined(IEEE_BIG_OR_LITTLE_ENDIAN)
03938 #define Exp_shift  20
03939 #define Exp_shift1 20
03940 #define Exp_msk1    0x100000
03941 #define Exp_msk11   0x100000
03942 #define Exp_mask  0x7ff00000
03943 #define P 53
03944 #define Bias 1023
03945 #define IEEE_Arith
03946 #define Emin (-1022)
03947 #define Exp_1  0x3ff00000
03948 #define Exp_11 0x3ff00000
03949 #define Ebits 11
03950 #define Frac_mask  0xfffff
03951 #define Frac_mask1 0xfffff
03952 #define Ten_pmax 22
03953 #define Bletch 0x10
03954 #define Bndry_mask  0xfffff
03955 #define Bndry_mask1 0xfffff
03956 #define LSB 1
03957 #define Sign_bit 0x80000000
03958 #define Log2P 1
03959 #define Tiny0 0
03960 #define Tiny1 1
03961 #define Quick_max 14
03962 #define Int_max 14
03963 #define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
03964 #else
03965 #undef  Sudden_Underflow
03966 #define Sudden_Underflow
03967 #ifdef IBM
03968 #define Exp_shift  24
03969 #define Exp_shift1 24
03970 #define Exp_msk1   0x1000000
03971 #define Exp_msk11  0x1000000
03972 #define Exp_mask  0x7f000000
03973 #define P 14
03974 #define Bias 65
03975 #define Exp_1  0x41000000
03976 #define Exp_11 0x41000000
03977 #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
03978 #define Frac_mask  0xffffff
03979 #define Frac_mask1 0xffffff
03980 #define Bletch 4
03981 #define Ten_pmax 22
03982 #define Bndry_mask  0xefffff
03983 #define Bndry_mask1 0xffffff
03984 #define LSB 1
03985 #define Sign_bit 0x80000000
03986 #define Log2P 4
03987 #define Tiny0 0x100000
03988 #define Tiny1 0
03989 #define Quick_max 14
03990 #define Int_max 15
03991 #else /* VAX */
03992 #define Exp_shift  23
03993 #define Exp_shift1 7
03994 #define Exp_msk1    0x80
03995 #define Exp_msk11   0x800000
03996 #define Exp_mask  0x7f80
03997 #define P 56
03998 #define Bias 129
03999 #define Exp_1  0x40800000
04000 #define Exp_11 0x4080
04001 #define Ebits 8
04002 #define Frac_mask  0x7fffff
04003 #define Frac_mask1 0xffff007f
04004 #define Ten_pmax 24
04005 #define Bletch 2
04006 #define Bndry_mask  0xffff007f
04007 #define Bndry_mask1 0xffff007f
04008 #define LSB 0x10000
04009 #define Sign_bit 0x8000
04010 #define Log2P 1
04011 #define Tiny0 0x80
04012 #define Tiny1 0
04013 #define Quick_max 15
04014 #define Int_max 15
04015 #endif
04016 #endif
04017 
04018 #ifndef IEEE_Arith
04019 #define ROUND_BIASED
04020 #endif
04021 
04022 #ifdef RND_PRODQUOT
04023 #define rounded_product(a,b) a = rnd_prod(a, b)
04024 #define rounded_quotient(a,b) a = rnd_quot(a, b)
04025 #ifdef KR_headers
04026 extern double rnd_prod(), rnd_quot();
04027 #else
04028 extern double rnd_prod(double, double), rnd_quot(double, double);
04029 #endif
04030 #else
04031 #define rounded_product(a,b) a *= b
04032 #define rounded_quotient(a,b) a /= b
04033 #endif
04034 
04035 #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
04036 #define Big1 0xffffffff
04037 
04038 #ifndef Just_16
04039 /* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
04040  * This makes some inner loops simpler and sometimes saves work
04041  * during multiplications, but it often seems to make things slightly
04042  * slower.  Hence the default is now to store 32 bits per Long.
04043  */
04044 #ifndef Pack_32
04045 #define Pack_32
04046 #endif
04047 #endif
04048 
04049 #define Kmax 15
04050 
04051 struct
04052 Bigint {
04053     struct Bigint *next;
04054     int k, maxwds, sign, wds;
04055     ULong x[1];
04056 };
04057 
04058  typedef struct Bigint Bigint;
04059 
04060 static Bigint *Balloc(int k)
04061 {
04062     int x;
04063     Bigint *rv;
04064 
04065     x = 1 << k;
04066     rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
04067     rv->k = k;
04068     rv->maxwds = x;
04069     rv->sign = rv->wds = 0;
04070     return rv;
04071 }
04072 
04073 static void Bfree(Bigint *v)
04074 {
04075     free(v);
04076 }
04077 
04078 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
04079 y->wds*sizeof(Long) + 2*sizeof(int))
04080 
04081 /* multiply by m and add a */
04082 static Bigint *multadd(Bigint *b, int m, int a)
04083 {
04084     int i, wds;
04085     ULong *x, y;
04086 #ifdef Pack_32
04087     ULong xi, z;
04088 #endif
04089     Bigint *b1;
04090 
04091     wds = b->wds;
04092     x = b->x;
04093     i = 0;
04094     do {
04095 #ifdef Pack_32
04096         xi = *x;
04097         y = (xi & 0xffff) * m + a;
04098         z = (xi >> 16) * m + (y >> 16);
04099         a = (int)(z >> 16);
04100         *x++ = (z << 16) + (y & 0xffff);
04101 #else
04102         y = *x * m + a;
04103         a = (int)(y >> 16);
04104         *x++ = y & 0xffff;
04105 #endif
04106     }
04107     while(++i < wds);
04108     if (a) {
04109         if (wds >= b->maxwds) {
04110             b1 = Balloc(b->k+1);
04111             Bcopy(b1, b);
04112             Bfree(b);
04113             b = b1;
04114         }
04115         b->x[wds++] = a;
04116         b->wds = wds;
04117     }
04118     return b;
04119 }
04120 
04121 static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9)
04122 {
04123     Bigint *b;
04124     int i, k;
04125     Long x, y;
04126 
04127     x = (nd + 8) / 9;
04128     for(k = 0, y = 1; x > y; y <<= 1, k++) ;
04129 #ifdef Pack_32
04130     b = Balloc(k);
04131     b->x[0] = y9;
04132     b->wds = 1;
04133 #else
04134     b = Balloc(k+1);
04135     b->x[0] = y9 & 0xffff;
04136     b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
04137 #endif
04138 
04139     i = 9;
04140     if (9 < nd0) {
04141         s += 9;
04142         do b = multadd(b, 10, *s++ - '0');
04143         while(++i < nd0);
04144         s++;
04145     }
04146     else
04147         s += 10;
04148     for(; i < nd; i++)
04149         b = multadd(b, 10, *s++ - '0');
04150     return b;
04151 }
04152 
04153 static int hi0bits(ULong x)
04154 {
04155     int k = 0;
04156 
04157     if (!(x & 0xffff0000)) {
04158         k = 16;
04159         x <<= 16;
04160     }
04161     if (!(x & 0xff000000)) {
04162         k += 8;
04163         x <<= 8;
04164     }
04165     if (!(x & 0xf0000000)) {
04166         k += 4;
04167         x <<= 4;
04168     }
04169     if (!(x & 0xc0000000)) {
04170         k += 2;
04171         x <<= 2;
04172     }
04173     if (!(x & 0x80000000)) {
04174         k++;
04175         if (!(x & 0x40000000))
04176             return 32;
04177     }
04178     return k;
04179 }
04180 
04181 static int lo0bits(ULong *y)
04182 {
04183     int k;
04184     ULong x = *y;
04185 
04186     if (x & 7) {
04187         if (x & 1)
04188             return 0;
04189         if (x & 2) {
04190             *y = x >> 1;
04191             return 1;
04192         }
04193         *y = x >> 2;
04194         return 2;
04195     }
04196     k = 0;
04197     if (!(x & 0xffff)) {
04198         k = 16;
04199         x >>= 16;
04200     }
04201     if (!(x & 0xff)) {
04202         k += 8;
04203         x >>= 8;
04204     }
04205     if (!(x & 0xf)) {
04206         k += 4;
04207         x >>= 4;
04208     }
04209     if (!(x & 0x3)) {
04210         k += 2;
04211         x >>= 2;
04212     }
04213     if (!(x & 1)) {
04214         k++;
04215         x >>= 1;
04216         if (!x & 1)
04217             return 32;
04218     }
04219     *y = x;
04220     return k;
04221 }
04222 
04223 static Bigint *i2b(int i)
04224 {
04225     Bigint *b;
04226 
04227     b = Balloc(1);
04228     b->x[0] = i;
04229     b->wds = 1;
04230     return b;
04231 }
04232 
04233 static Bigint *mult(Bigint *a, Bigint *b)
04234 {
04235     Bigint *c;
04236     int k, wa, wb, wc;
04237     ULong carry, y, z;
04238     ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
04239 #ifdef Pack_32
04240     ULong z2;
04241 #endif
04242 
04243     if (a->wds < b->wds) {
04244         c = a;
04245         a = b;
04246         b = c;
04247     }
04248     k = a->k;
04249     wa = a->wds;
04250     wb = b->wds;
04251     wc = wa + wb;
04252     if (wc > a->maxwds)
04253         k++;
04254     c = Balloc(k);
04255     for(x = c->x, xa = x + wc; x < xa; x++)
04256         *x = 0;
04257     xa = a->x;
04258     xae = xa + wa;
04259     xb = b->x;
04260     xbe = xb + wb;
04261     xc0 = c->x;
04262 #ifdef Pack_32
04263     for(; xb < xbe; xb++, xc0++) {
04264         if ((y = *xb & 0xffff) != 0) {
04265             x = xa;
04266             xc = xc0;
04267             carry = 0;
04268             do {
04269                 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
04270                 carry = z >> 16;
04271                 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
04272                 carry = z2 >> 16;
04273                 Storeinc(xc, z2, z);
04274             }
04275             while(x < xae);
04276             *xc = carry;
04277         }
04278         if ((y = *xb >> 16) != 0) {
04279             x = xa;
04280             xc = xc0;
04281             carry = 0;
04282             z2 = *xc;
04283             do {
04284                 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
04285                 carry = z >> 16;
04286                 Storeinc(xc, z, z2);
04287                 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
04288                 carry = z2 >> 16;
04289             }
04290             while(x < xae);
04291             *xc = z2;
04292         }
04293     }
04294 #else
04295     for(; xb < xbe; xc0++) {
04296         if (y = *xb++) {
04297             x = xa;
04298             xc = xc0;
04299             carry = 0;
04300             do {
04301                 z = *x++ * y + *xc + carry;
04302                 carry = z >> 16;
04303                 *xc++ = z & 0xffff;
04304             }
04305             while(x < xae);
04306             *xc = carry;
04307         }
04308     }
04309 #endif
04310     for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
04311     c->wds = wc;
04312     return c;
04313 }
04314 
04315 static Bigint *p5s;
04316 
04317 static Bigint *pow5mult(Bigint *b, int k)
04318 {
04319     Bigint *b1, *p5, *p51;
04320     int i;
04321     static const int p05[3] = { 5, 25, 125 };
04322 
04323     if ((i = k & 3) != 0)
04324         b = multadd(b, p05[i-1], 0);
04325 
04326     if (!(k >>= 2))
04327         return b;
04328     if (!(p5 = p5s)) {
04329         /* first time */
04330         p5 = p5s = i2b(625);
04331         p5->next = 0;
04332     }
04333     for(;;) {
04334         if (k & 1) {
04335             b1 = mult(b, p5);
04336             Bfree(b);
04337             b = b1;
04338         }
04339         if (!(k >>= 1))
04340             break;
04341         if (!(p51 = p5->next)) {
04342             p51 = p5->next = mult(p5,p5);
04343             p51->next = 0;
04344         }
04345         p5 = p51;
04346     }
04347     return b;
04348 }
04349 
04350 static Bigint *lshift(Bigint *b, int k)
04351 {
04352     int i, k1, n, n1;
04353     Bigint *b1;
04354     ULong *x, *x1, *xe, z;
04355 
04356 #ifdef Pack_32
04357     n = k >> 5;
04358 #else
04359     n = k >> 4;
04360 #endif
04361     k1 = b->k;
04362     n1 = n + b->wds + 1;
04363     for(i = b->maxwds; n1 > i; i <<= 1)
04364         k1++;
04365     b1 = Balloc(k1);
04366     x1 = b1->x;
04367     for(i = 0; i < n; i++)
04368         *x1++ = 0;
04369     x = b->x;
04370     xe = x + b->wds;
04371 #ifdef Pack_32
04372     if (k &= 0x1f) {
04373         k1 = 32 - k;
04374         z = 0;
04375         do {
04376             *x1++ = *x << k | z;
04377             z = *x++ >> k1;
04378         }
04379         while(x < xe);
04380         if ((*x1 = z) != 0)
04381             ++n1;
04382     }
04383 #else
04384     if (k &= 0xf) {
04385         k1 = 16 - k;
04386         z = 0;
04387         do {
04388             *x1++ = *x << k  & 0xffff | z;
04389             z = *x++ >> k1;
04390         }
04391         while(x < xe);
04392         if (*x1 = z)
04393             ++n1;
04394     }
04395 #endif
04396     else do
04397         *x1++ = *x++;
04398     while(x < xe);
04399     b1->wds = n1 - 1;
04400     Bfree(b);
04401     return b1;
04402 }
04403 
04404 static int cmp(Bigint *a, Bigint *b)
04405 {
04406     ULong *xa, *xa0, *xb, *xb0;
04407     int i, j;
04408 
04409     i = a->wds;
04410     j = b->wds;
04411 #ifdef BSD_QDTOA_DEBUG
04412     if (i > 1 && !a->x[i-1])
04413         Bug("cmp called with a->x[a->wds-1] == 0");
04414     if (j > 1 && !b->x[j-1])
04415         Bug("cmp called with b->x[b->wds-1] == 0");
04416 #endif
04417     if (i -= j)
04418         return i;
04419     xa0 = a->x;
04420     xa = xa0 + j;
04421     xb0 = b->x;
04422     xb = xb0 + j;
04423     for(;;) {
04424         if (*--xa != *--xb)
04425             return *xa < *xb ? -1 : 1;
04426         if (xa <= xa0)
04427             break;
04428     }
04429     return 0;
04430 }
04431 
04432 static Bigint *diff(Bigint *a, Bigint *b)
04433 {
04434     Bigint *c;
04435     int i, wa, wb;
04436     Long borrow, y;     /* We need signed shifts here. */
04437     ULong *xa, *xae, *xb, *xbe, *xc;
04438 #ifdef Pack_32
04439     Long z;
04440 #endif
04441 
04442     i = cmp(a,b);
04443     if (!i) {
04444         c = Balloc(0);
04445         c->wds = 1;
04446         c->x[0] = 0;
04447         return c;
04448     }
04449     if (i < 0) {
04450         c = a;
04451         a = b;
04452         b = c;
04453         i = 1;
04454     }
04455     else
04456         i = 0;
04457     c = Balloc(a->k);
04458     c->sign = i;
04459     wa = a->wds;
04460     xa = a->x;
04461     xae = xa + wa;
04462     wb = b->wds;
04463     xb = b->x;
04464     xbe = xb + wb;
04465     xc = c->x;
04466     borrow = 0;
04467 #ifdef Pack_32
04468     do {
04469         y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
04470         borrow = y >> 16;
04471         Sign_Extend(borrow, y);
04472         z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
04473         borrow = z >> 16;
04474         Sign_Extend(borrow, z);
04475         Storeinc(xc, z, y);
04476     }
04477     while(xb < xbe);
04478     while(xa < xae) {
04479         y = (*xa & 0xffff) + borrow;
04480         borrow = y >> 16;
04481         Sign_Extend(borrow, y);
04482         z = (*xa++ >> 16) + borrow;
04483         borrow = z >> 16;
04484         Sign_Extend(borrow, z);
04485         Storeinc(xc, z, y);
04486     }
04487 #else
04488     do {
04489         y = *xa++ - *xb++ + borrow;
04490         borrow = y >> 16;
04491         Sign_Extend(borrow, y);
04492         *xc++ = y & 0xffff;
04493     }
04494     while(xb < xbe);
04495     while(xa < xae) {
04496         y = *xa++ + borrow;
04497         borrow = y >> 16;
04498         Sign_Extend(borrow, y);
04499         *xc++ = y & 0xffff;
04500     }
04501 #endif
04502     while(!*--xc)
04503         wa--;
04504     c->wds = wa;
04505     return c;
04506 }
04507 
04508 static double ulp(volatile double x)
04509 {
04510     Long L;
04511     double a;
04512 
04513     L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
04514 #ifndef Sudden_Underflow
04515     if (L > 0) {
04516 #endif
04517 #ifdef IBM
04518         L |= Exp_msk1 >> 4;
04519 #endif
04520         word0(a) = L;
04521         word1(a) = 0;
04522 #ifndef Sudden_Underflow
04523     }
04524     else {
04525         L = -L >> Exp_shift;
04526         if (L < Exp_shift) {
04527             word0(a) = 0x80000 >> L;
04528             word1(a) = 0;
04529         }
04530         else {
04531             word0(a) = 0;
04532             L -= Exp_shift;
04533             word1(a) = (L >= 31 ? 1U : 1U << (31 - L));
04534         }
04535     }
04536 #endif
04537     return a;
04538 }
04539 
04540 static double b2d(Bigint *a, int *e)
04541 {
04542     ULong *xa, *xa0, w, y, z;
04543     int k;
04544     double d;
04545 #ifdef VAX
04546     ULong d0, d1;
04547 #else
04548 #define d0 word0(d)
04549 #define d1 word1(d)
04550 #endif
04551 
04552     xa0 = a->x;
04553     xa = xa0 + a->wds;
04554     y = *--xa;
04555 #ifdef BSD_QDTOA_DEBUG
04556     if (!y) Bug("zero y in b2d");
04557 #endif
04558     k = hi0bits(y);
04559     *e = 32 - k;
04560 #ifdef Pack_32
04561     if (k < Ebits) {
04562         d0 = Exp_1 | y >> (Ebits - k);
04563         w = xa > xa0 ? *--xa : 0;
04564         d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
04565         goto ret_d;
04566     }
04567     z = xa > xa0 ? *--xa : 0;
04568     if (k -= Ebits) {
04569         d0 = Exp_1 | y << k | z >> (32 - k);
04570         y = xa > xa0 ? *--xa : 0;
04571         d1 = z << k | y >> (32 - k);
04572     }
04573     else {
04574         d0 = Exp_1 | y;
04575         d1 = z;
04576     }
04577 #else
04578     if (k < Ebits + 16) {
04579         z = xa > xa0 ? *--xa : 0;
04580         d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
04581         w = xa > xa0 ? *--xa : 0;
04582         y = xa > xa0 ? *--xa : 0;
04583         d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
04584         goto ret_d;
04585     }
04586     z = xa > xa0 ? *--xa : 0;
04587     w = xa > xa0 ? *--xa : 0;
04588     k -= Ebits + 16;
04589     d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
04590     y = xa > xa0 ? *--xa : 0;
04591     d1 = w << k + 16 | y << k;
04592 #endif
04593  ret_d:
04594 #ifdef VAX
04595     word0(d) = d0 >> 16 | d0 << 16;
04596     word1(d) = d1 >> 16 | d1 << 16;
04597 #else
04598 #undef d0
04599 #undef d1
04600 #endif
04601     return d;
04602 }
04603 
04604 static Bigint *d2b(double d, int *e, int *bits)
04605 {
04606     Bigint *b;
04607     int de, i, k;
04608     ULong *x, y, z;
04609 #ifdef VAX
04610     ULong d0, d1;
04611     d0 = word0(d) >> 16 | word0(d) << 16;
04612     d1 = word1(d) >> 16 | word1(d) << 16;
04613 #else
04614 #define d0 word0(d)
04615 #define d1 word1(d)
04616 #endif
04617 
04618 #ifdef Pack_32
04619     b = Balloc(1);
04620 #else
04621     b = Balloc(2);
04622 #endif
04623     x = b->x;
04624 
04625     z = d0 & Frac_mask;
04626     d0 &= 0x7fffffff;   /* clear sign bit, which we ignore */
04627 #ifdef Sudden_Underflow
04628     de = (int)(d0 >> Exp_shift);
04629 #ifndef IBM
04630     z |= Exp_msk11;
04631 #endif
04632 #else
04633     if ((de = (int)(d0 >> Exp_shift)) != 0)
04634         z |= Exp_msk1;
04635 #endif
04636 #ifdef Pack_32
04637     if ((y = d1) != 0) {
04638         if ((k = lo0bits(&y)) != 0) {
04639             x[0] = y | z << (32 - k);
04640             z >>= k;
04641         }
04642         else
04643             x[0] = y;
04644         i = b->wds = (x[1] = z) ? 2 : 1;
04645     }
04646     else {
04647 #ifdef BSD_QDTOA_DEBUG
04648         if (!z)
04649             Bug("Zero passed to d2b");
04650 #endif
04651         k = lo0bits(&z);
04652         x[0] = z;
04653         i = b->wds = 1;
04654         k += 32;
04655     }
04656 #else
04657     if (y = d1) {
04658         if (k = lo0bits(&y))
04659             if (k >= 16) {
04660                 x[0] = y | z << 32 - k & 0xffff;
04661                 x[1] = z >> k - 16 & 0xffff;
04662                 x[2] = z >> k;
04663                 i = 2;
04664             }
04665             else {
04666                 x[0] = y & 0xffff;
04667                 x[1] = y >> 16 | z << 16 - k & 0xffff;
04668                 x[2] = z >> k & 0xffff;
04669                 x[3] = z >> k+16;
04670                 i = 3;
04671             }
04672         else {
04673             x[0] = y & 0xffff;
04674             x[1] = y >> 16;
04675             x[2] = z & 0xffff;
04676             x[3] = z >> 16;
04677             i = 3;
04678         }
04679     }
04680     else {
04681 #ifdef BSD_QDTOA_DEBUG
04682         if (!z)
04683             Bug("Zero passed to d2b");
04684 #endif
04685         k = lo0bits(&z);
04686         if (k >= 16) {
04687             x[0] = z;
04688             i = 0;
04689         }
04690         else {
04691             x[0] = z & 0xffff;
04692             x[1] = z >> 16;
04693             i = 1;
04694         }
04695         k += 32;
04696     }
04697     while(!x[i])
04698         --i;
04699     b->wds = i + 1;
04700 #endif
04701 #ifndef Sudden_Underflow
04702     if (de) {
04703 #endif
04704 #ifdef IBM
04705         *e = (de - Bias - (P-1) << 2) + k;
04706         *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
04707 #else
04708         *e = de - Bias - (P-1) + k;
04709         *bits = P - k;
04710 #endif
04711 #ifndef Sudden_Underflow
04712     }
04713     else {
04714         *e = de - Bias - (P-1) + 1 + k;
04715 #ifdef Pack_32
04716         *bits = 32*i - hi0bits(x[i-1]);
04717 #else
04718         *bits = (i+2)*16 - hi0bits(x[i]);
04719 #endif
04720     }
04721 #endif
04722     return b;
04723 }
04724 #undef d0
04725 #undef d1
04726 
04727 static double ratio(Bigint *a, Bigint *b)
04728 {
04729     double da, db;
04730     int k, ka, kb;
04731 
04732     da = b2d(a, &ka);
04733     db = b2d(b, &kb);
04734 #ifdef Pack_32
04735     k = ka - kb + 32*(a->wds - b->wds);
04736 #else
04737     k = ka - kb + 16*(a->wds - b->wds);
04738 #endif
04739 #ifdef IBM
04740     if (k > 0) {
04741         word0(da) += (k >> 2)*Exp_msk1;
04742         if (k &= 3)
04743             da *= 1 << k;
04744     }
04745     else {
04746         k = -k;
04747         word0(db) += (k >> 2)*Exp_msk1;
04748         if (k &= 3)
04749             db *= 1 << k;
04750     }
04751 #else
04752     if (k > 0)
04753         word0(da) += k*Exp_msk1;
04754     else {
04755         k = -k;
04756         word0(db) += k*Exp_msk1;
04757     }
04758 #endif
04759     return da / db;
04760 }
04761 
04762 static CONST double tens[] = {
04763     1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
04764     1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
04765     1e20, 1e21, 1e22
04766 #ifdef VAX
04767     , 1e23, 1e24
04768 #endif
04769 };
04770 
04771 #ifdef IEEE_Arith
04772 static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
04773 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
04774 #define n_bigtens 5
04775 #else
04776 #ifdef IBM
04777 static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
04778 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
04779 #define n_bigtens 3
04780 #else
04781 static CONST double bigtens[] = { 1e16, 1e32 };
04782 static CONST double tinytens[] = { 1e-16, 1e-32 };
04783 #define n_bigtens 2
04784 #endif
04785 #endif
04786 
04787 /*
04788   The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes
04789   the comparison 1e-100 == 0.0 to return true. As a workaround, we
04790   compare it to a global variable containing 0.0, which produces
04791   correct assembler output.
04792 
04793   ### consider detecting the broken compilers and using the static
04794   ### double for these, and use a #define for all working compilers
04795 */
04796 static double g_double_zero = 0.0;
04797 
04798 static double qstrtod(CONST char *s00, CONST char **se, bool *ok)
04799 {
04800     int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
04801         e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
04802     CONST char *s, *s0, *s1;
04803     double aadj, aadj1, adj, rv, rv0;
04804     Long L;
04805     ULong y, z;
04806     Bigint *bb1, *bd0;
04807     Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
04808 
04809     /*
04810       #ifndef KR_headers
04811       CONST char decimal_point = localeconv()->decimal_point[0];
04812       #else
04813       CONST char decimal_point = '.';
04814       #endif */
04815     if (ok != 0)
04816         *ok = true;
04817 
04818     CONST char decimal_point = '.';
04819 
04820     sign = nz0 = nz = 0;
04821     rv = 0.;
04822 
04823 
04824     for(s = s00; isspace((unsigned char) *s); s++)
04825         ;
04826 
04827     if (*s == '-') {
04828         sign = 1;
04829         s++;
04830     } else if (*s == '+') {
04831         s++;
04832     }
04833 
04834     if (*s == '\0') {
04835         s = s00;
04836         goto ret;
04837     }
04838 
04839     if (*s == '0') {
04840         nz0 = 1;
04841         while(*++s == '0') ;
04842         if (!*s)
04843             goto ret;
04844     }
04845     s0 = s;
04846     y = z = 0;
04847     for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
04848         if (nd < 9)
04849             y = 10*y + c - '0';
04850         else if (nd < 16)
04851             z = 10*z + c - '0';
04852     nd0 = nd;
04853     if (c == decimal_point) {
04854         c = *++s;
04855         if (!nd) {
04856             for(; c == '0'; c = *++s)
04857                 nz++;
04858             if (c > '0' && c <= '9') {
04859                 s0 = s;
04860                 nf += nz;
04861                 nz = 0;
04862                 goto have_dig;
04863             }
04864             goto dig_done;
04865         }
04866         for(; c >= '0' && c <= '9'; c = *++s) {
04867         have_dig:
04868             nz++;
04869             if (c -= '0') {
04870                 nf += nz;
04871                 for(i = 1; i < nz; i++)
04872                     if (nd++ < 9)
04873                         y *= 10;
04874                     else if (nd <= DBL_DIG + 1)
04875                         z *= 10;
04876                 if (nd++ < 9)
04877                     y = 10*y + c;
04878                 else if (nd <= DBL_DIG + 1)
04879                     z = 10*z + c;
04880                 nz = 0;
04881             }
04882         }
04883     }
04884  dig_done:
04885     e = 0;
04886     if (c == 'e' || c == 'E') {
04887         if (!nd && !nz && !nz0) {
04888             s = s00;
04889             goto ret;
04890         }
04891         s00 = s;
04892         esign = 0;
04893         switch(c = *++s) {
04894         case '-':
04895             esign = 1;
04896         case '+':
04897             c = *++s;
04898         }
04899         if (c >= '0' && c <= '9') {
04900             while(c == '0')
04901                 c = *++s;
04902             if (c > '0' && c <= '9') {
04903                 L = c - '0';
04904                 s1 = s;
04905                 while((c = *++s) >= '0' && c <= '9')
04906                     L = 10*L + c - '0';
04907                 if (s - s1 > 8 || L > 19999)
04908                     /* Avoid confusion from exponents
04909                      * so large that e might overflow.
04910                      */
04911                     e = 19999; /* safe for 16 bit ints */
04912                 else
04913                     e = (int)L;
04914                 if (esign)
04915                     e = -e;
04916             }
04917             else
04918                 e = 0;
04919         }
04920         else
04921             s = s00;
04922     }
04923     if (!nd) {
04924         if (!nz && !nz0)
04925             s = s00;
04926         goto ret;
04927     }
04928     e1 = e -= nf;
04929 
04930     /* Now we have nd0 digits, starting at s0, followed by a
04931      * decimal point, followed by nd-nd0 digits.  The number we're
04932      * after is the integer represented by those digits times
04933      * 10**e */
04934 
04935     if (!nd0)
04936         nd0 = nd;
04937     k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
04938     rv = y;
04939     if (k > 9)
04940         rv = tens[k - 9] * rv + z;
04941     bd0 = 0;
04942     if (nd <= DBL_DIG
04943 #ifndef RND_PRODQUOT
04944         && FLT_ROUNDS == 1
04945 #endif
04946         ) {
04947         if (!e)
04948             goto ret;
04949         if (e > 0) {
04950             if (e <= Ten_pmax) {
04951 #ifdef VAX
04952                 goto vax_ovfl_check;
04953 #else
04954                 /* rv = */ rounded_product(rv, tens[e]);
04955                 goto ret;
04956 #endif
04957             }
04958             i = DBL_DIG - nd;
04959             if (e <= Ten_pmax + i) {
04960                 /* A fancier test would sometimes let us do
04961                  * this for larger i values.
04962                  */
04963                 e -= i;
04964                 rv *= tens[i];
04965 #ifdef VAX
04966                 /* VAX exponent range is so narrow we must
04967                  * worry about overflow here...
04968                  */
04969             vax_ovfl_check:
04970                 word0(rv) -= P*Exp_msk1;
04971                 /* rv = */ rounded_product(rv, tens[e]);
04972                 if ((word0(rv) & Exp_mask)
04973                     > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
04974                     goto ovfl;
04975                 word0(rv) += P*Exp_msk1;
04976 #else
04977                 /* rv = */ rounded_product(rv, tens[e]);
04978 #endif
04979                 goto ret;
04980             }
04981         }
04982 #ifndef Inaccurate_Divide
04983         else if (e >= -Ten_pmax) {
04984             /* rv = */ rounded_quotient(rv, tens[-e]);
04985             goto ret;
04986         }
04987 #endif
04988     }
04989     e1 += nd - k;
04990 
04991     /* Get starting approximation = rv * 10**e1 */
04992 
04993     if (e1 > 0) {
04994         if ((i = e1 & 15) != 0)
04995             rv *= tens[i];
04996         if (e1 &= ~15) {
04997             if (e1 > DBL_MAX_10_EXP) {
04998             ovfl:
04999                 //                              errno = ERANGE;
05000                 if (ok != 0)
05001                     *ok = false;
05002 #ifdef __STDC__
05003                 rv = HUGE_VAL;
05004 #else
05005                 /* Can't trust HUGE_VAL */
05006 #ifdef IEEE_Arith
05007                 word0(rv) = Exp_mask;
05008                 word1(rv) = 0;
05009 #else
05010                 word0(rv) = Big0;
05011                 word1(rv) = Big1;
05012 #endif
05013 #endif
05014                 if (bd0)
05015                     goto retfree;
05016                 goto ret;
05017             }
05018             if (e1 >>= 4) {
05019                 for(j = 0; e1 > 1; j++, e1 >>= 1)
05020                     if (e1 & 1)
05021                         rv *= bigtens[j];
05022                 /* The last multiplication could overflow. */
05023                 word0(rv) -= P*Exp_msk1;
05024                 rv *= bigtens[j];
05025                 if ((z = word0(rv) & Exp_mask)
05026                     > Exp_msk1*(DBL_MAX_EXP+Bias-P))
05027                     goto ovfl;
05028                 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
05029                     /* set to largest number */
05030                     /* (Can't trust DBL_MAX) */
05031                     word0(rv) = Big0;
05032                     word1(rv) = Big1;
05033                 }
05034                 else
05035                     word0(rv) += P*Exp_msk1;
05036             }
05037 
05038         }
05039     }
05040     else if (e1 < 0) {
05041         e1 = -e1;
05042         if ((i = e1 & 15) != 0)
05043             rv /= tens[i];
05044         if (e1 &= ~15) {
05045             e1 >>= 4;
05046             if (e1 >= 1 << n_bigtens)
05047                 goto undfl;
05048             for(j = 0; e1 > 1; j++, e1 >>= 1)
05049                 if (e1 & 1)
05050                     rv *= tinytens[j];
05051             /* The last multiplication could underflow. */
05052             rv0 = rv;
05053             rv *= tinytens[j];
05054             if (rv == g_double_zero)
05055                 {
05056                     rv = 2.*rv0;
05057                     rv *= tinytens[j];
05058                     if (rv == g_double_zero)
05059                         {
05060                         undfl:
05061                             rv = 0.;
05062                             //                                  errno = ERANGE;
05063                             if (ok != 0)
05064                                 *ok = false;
05065                             if (bd0)
05066                                 goto retfree;
05067                             goto ret;
05068                         }
05069                     word0(rv) = Tiny0;
05070                     word1(rv) = Tiny1;
05071                     /* The refinement below will clean
05072                      * this approximation up.
05073                      */
05074                 }
05075         }
05076     }
05077 
05078     /* Now the hard part -- adjusting rv to the correct value.*/
05079 
05080     /* Put digits into bd: true value = bd * 10^e */
05081 
05082     bd0 = s2b(s0, nd0, nd, y);
05083 
05084     for(;;) {
05085         bd = Balloc(bd0->k);
05086         Bcopy(bd, bd0);
05087         bb = d2b(rv, &bbe, &bbbits);    /* rv = bb * 2^bbe */
05088         bs = i2b(1);
05089 
05090         if (e >= 0) {
05091             bb2 = bb5 = 0;
05092             bd2 = bd5 = e;
05093         }
05094         else {
05095             bb2 = bb5 = -e;
05096             bd2 = bd5 = 0;
05097         }
05098         if (bbe >= 0)
05099             bb2 += bbe;
05100         else
05101             bd2 -= bbe;
05102         bs2 = bb2;
05103 #ifdef Sudden_Underflow
05104 #ifdef IBM
05105         j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
05106 #else
05107         j = P + 1 - bbbits;
05108 #endif
05109 #else
05110         i = bbe + bbbits - 1;   /* logb(rv) */
05111         if (i < Emin)   /* denormal */
05112             j = bbe + (P-Emin);
05113         else
05114             j = P + 1 - bbbits;
05115 #endif
05116         bb2 += j;
05117         bd2 += j;
05118         i = bb2 < bd2 ? bb2 : bd2;
05119         if (i > bs2)
05120             i = bs2;
05121         if (i > 0) {
05122             bb2 -= i;
05123             bd2 -= i;
05124             bs2 -= i;
05125         }
05126         if (bb5 > 0) {
05127             bs = pow5mult(bs, bb5);
05128             bb1 = mult(bs, bb);
05129             Bfree(bb);
05130             bb = bb1;
05131         }
05132         if (bb2 > 0)
05133             bb = lshift(bb, bb2);
05134         if (bd5 > 0)
05135             bd = pow5mult(bd, bd5);
05136         if (bd2 > 0)
05137             bd = lshift(bd, bd2);
05138         if (bs2 > 0)
05139             bs = lshift(bs, bs2);
05140         delta = diff(bb, bd);
05141         dsign = delta->sign;
05142         delta->sign = 0;
05143         i = cmp(delta, bs);
05144         if (i < 0) {
05145             /* Error is less than half an ulp -- check for
05146              * special case of mantissa a power of two.
05147              */
05148             if (dsign || word1(rv) || word0(rv) & Bndry_mask)
05149                 break;
05150             delta = lshift(delta,Log2P);
05151             if (cmp(delta, bs) > 0)
05152                 goto drop_down;
05153             break;
05154         }
05155         if (i == 0) {
05156             /* exactly half-way between */
05157             if (dsign) {
05158                 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
05159                     &&  word1(rv) == 0xffffffff) {
05160                     /*boundary case -- increment exponent*/
05161                     word0(rv) = (word0(rv) & Exp_mask)
05162                                 + Exp_msk1
05163 #ifdef IBM
05164                                 | Exp_msk1 >> 4
05165 #endif
05166                                 ;
05167                     word1(rv) = 0;
05168                     break;
05169                 }
05170             }
05171             else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
05172             drop_down:
05173                 /* boundary case -- decrement exponent */
05174 #ifdef Sudden_Underflow
05175                 L = word0(rv) & Exp_mask;
05176 #ifdef IBM
05177                 if (L <  Exp_msk1)
05178 #else
05179                     if (L <= Exp_msk1)
05180 #endif
05181                         goto undfl;
05182                 L -= Exp_msk1;
05183 #else
05184                 L = (word0(rv) & Exp_mask) - Exp_msk1;
05185 #endif
05186                 word0(rv) = L | Bndry_mask1;
05187                 word1(rv) = 0xffffffff;
05188 #ifdef IBM
05189                 goto cont;
05190 #else
05191                 break;
05192 #endif
05193             }
05194 #ifndef ROUND_BIASED
05195             if (!(word1(rv) & LSB))
05196                 break;
05197 #endif
05198             if (dsign)
05199                 rv += ulp(rv);
05200 #ifndef ROUND_BIASED
05201             else {
05202                 rv -= ulp(rv);
05203 #ifndef Sudden_Underflow
05204                 if (rv == g_double_zero)
05205                     goto undfl;
05206 #endif
05207             }
05208 #endif
05209             break;
05210         }
05211         if ((aadj = ratio(delta, bs)) <= 2.) {
05212             if (dsign)
05213                 aadj = aadj1 = 1.;
05214             else if (word1(rv) || word0(rv) & Bndry_mask) {
05215 #ifndef Sudden_Underflow
05216                 if (word1(rv) == Tiny1 && !word0(rv))
05217                     goto undfl;
05218 #endif
05219                 aadj = 1.;
05220                 aadj1 = -1.;
05221             }
05222             else {
05223                 /* special case -- power of FLT_RADIX to be */
05224                 /* rounded down... */
05225 
05226                 if (aadj < 2./FLT_RADIX)
05227                     aadj = 1./FLT_RADIX;
05228                 else
05229                     aadj *= 0.5;
05230                 aadj1 = -aadj;
05231             }
05232         }
05233         else {
05234             aadj *= 0.5;
05235             aadj1 = dsign ? aadj : -aadj;
05236 #ifdef Check_FLT_ROUNDS
05237             switch(FLT_ROUNDS) {
05238             case 2: /* towards +infinity */
05239                 aadj1 -= 0.5;
05240                 break;
05241             case 0: /* towards 0 */
05242             case 3: /* towards -infinity */
05243                 aadj1 += 0.5;
05244             }
05245 #else
05246             if (FLT_ROUNDS == 0)
05247                 aadj1 += 0.5;
05248 #endif
05249         }
05250         y = word0(rv) & Exp_mask;
05251 
05252         /* Check for overflow */
05253 
05254         if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
05255             rv0 = rv;
05256             word0(rv) -= P*Exp_msk1;
05257             adj = aadj1 * ulp(rv);
05258             rv += adj;
05259             if ((word0(rv) & Exp_mask) >=
05260                 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
05261                 if (word0(rv0) == Big0 && word1(rv0) == Big1)
05262                     goto ovfl;
05263                 word0(rv) = Big0;
05264                 word1(rv) = Big1;
05265                 goto cont;
05266             }
05267             else
05268                 word0(rv) += P*Exp_msk1;
05269         }
05270         else {
05271 #ifdef Sudden_Underflow
05272             if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
05273                 rv0 = rv;
05274                 word0(rv) += P*Exp_msk1;
05275                 adj = aadj1 * ulp(rv);
05276                 rv += adj;
05277 #ifdef IBM
05278                 if ((word0(rv) & Exp_mask) <  P*Exp_msk1)
05279 #else
05280                     if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
05281 #endif
05282                         {
05283                             if (word0(rv0) == Tiny0
05284                                 && word1(rv0) == Tiny1)
05285                                 goto undfl;
05286                             word0(rv) = Tiny0;
05287                             word1(rv) = Tiny1;
05288                             goto cont;
05289                         }
05290                     else
05291                         word0(rv) -= P*Exp_msk1;
05292             }
05293             else {
05294                 adj = aadj1 * ulp(rv);
05295                 rv += adj;
05296             }
05297 #else
05298             /* Compute adj so that the IEEE rounding rules will
05299              * correctly round rv + adj in some half-way cases.
05300              * If rv * ulp(rv) is denormalized (i.e.,
05301              * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
05302              * trouble from bits lost to denormalization;
05303              * example: 1.2e-307 .
05304              */
05305             if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
05306                 aadj1 = (double)(int)(aadj + 0.5);
05307                 if (!dsign)
05308                     aadj1 = -aadj1;
05309             }
05310             adj = aadj1 * ulp(rv);
05311             rv += adj;
05312 #endif
05313         }
05314         z = word0(rv) & Exp_mask;
05315         if (y == z) {
05316             /* Can we stop now? */
05317             L = (Long) aadj;
05318             aadj -= L;
05319             /* The tolerances below are conservative. */
05320             if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
05321                 if (aadj < .4999999 || aadj > .5000001)
05322                     break;
05323             }
05324             else if (aadj < .4999999/FLT_RADIX)
05325                 break;
05326         }
05327     cont:
05328         Bfree(bb);
05329         Bfree(bd);
05330         Bfree(bs);
05331         Bfree(delta);
05332     }
05333  retfree:
05334     Bfree(bb);
05335     Bfree(bd);
05336     Bfree(bs);
05337     Bfree(bd0);
05338     Bfree(delta);
05339  ret:
05340     if (se)
05341         *se = (char *)s;
05342     return sign ? -rv : rv;
05343 }
05344 
05345 static int quorem(Bigint *b, Bigint *S)
05346 {
05347     int n;
05348     Long borrow, y;
05349     ULong carry, q, ys;
05350     ULong *bx, *bxe, *sx, *sxe;
05351 #ifdef Pack_32
05352     Long z;
05353     ULong si, zs;
05354 #endif
05355 
05356     n = S->wds;
05357 #ifdef BSD_QDTOA_DEBUG
05358     /*debug*/ if (b->wds > n)
05359         /*debug*/       Bug("oversize b in quorem");
05360 #endif
05361     if (b->wds < n)
05362         return 0;
05363     sx = S->x;
05364     sxe = sx + --n;
05365     bx = b->x;
05366     bxe = bx + n;
05367     q = *bxe / (*sxe + 1);      /* ensure q <= true quotient */
05368 #ifdef BSD_QDTOA_DEBUG
05369     /*debug*/ if (q > 9)
05370         /*debug*/       Bug("oversized quotient in quorem");
05371 #endif
05372     if (q) {
05373         borrow = 0;
05374         carry = 0;
05375         do {
05376 #ifdef Pack_32
05377             si = *sx++;
05378             ys = (si & 0xffff) * q + carry;
05379             zs = (si >> 16) * q + (ys >> 16);
05380             carry = zs >> 16;
05381             y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
05382             borrow = y >> 16;
05383             Sign_Extend(borrow, y);
05384             z = (*bx >> 16) - (zs & 0xffff) + borrow;
05385             borrow = z >> 16;
05386             Sign_Extend(borrow, z);
05387             Storeinc(bx, z, y);
05388 #else
05389             ys = *sx++ * q + carry;
05390             carry = ys >> 16;
05391             y = *bx - (ys & 0xffff) + borrow;
05392             borrow = y >> 16;
05393             Sign_Extend(borrow, y);
05394             *bx++ = y & 0xffff;
05395 #endif
05396         }
05397         while(sx <= sxe);
05398         if (!*bxe) {
05399             bx = b->x;
05400             while(--bxe > bx && !*bxe)
05401                 --n;
05402             b->wds = n;
05403         }
05404     }
05405     if (cmp(b, S) >= 0) {
05406         q++;
05407         borrow = 0;
05408         carry = 0;
05409         bx = b->x;
05410         sx = S->x;
05411         do {
05412 #ifdef Pack_32
05413             si = *sx++;
05414             ys = (si & 0xffff) + carry;
05415             zs = (si >> 16) + (ys >> 16);
05416             carry = zs >> 16;
05417             y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
05418             borrow = y >> 16;
05419             Sign_Extend(borrow, y);
05420             z = (*bx >> 16) - (zs & 0xffff) + borrow;
05421             borrow = z >> 16;
05422             Sign_Extend(borrow, z);
05423             Storeinc(bx, z, y);
05424 #else
05425             ys = *sx++ + carry;
05426             carry = ys >> 16;
05427             y = *bx - (ys & 0xffff) + borrow;
05428             borrow = y >> 16;
05429             Sign_Extend(borrow, y);
05430             *bx++ = y & 0xffff;
05431 #endif
05432         }
05433         while(sx <= sxe);
05434         bx = b->x;
05435         bxe = bx + n;
05436         if (!*bxe) {
05437             while(--bxe > bx && !*bxe)
05438                 --n;
05439             b->wds = n;
05440         }
05441     }
05442     return q;
05443 }
05444 
05445 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
05446  *
05447  * Inspired by "How to Print Floating-Point Numbers Accurately" by
05448  * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
05449  *
05450  * Modifications:
05451  *      1. Rather than iterating, we use a simple numeric overestimate
05452  *         to determine k = floor(log10(d)).  We scale relevant
05453  *         quantities using O(log2(k)) rather than O(k) multiplications.
05454  *      2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
05455  *         try to generate digits strictly left to right.  Instead, we
05456  *         compute with fewer bits and propagate the carry if necessary
05457  *         when rounding the final digit up.  This is often faster.
05458  *      3. Under the assumption that input will be rounded nearest,
05459  *         mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
05460  *         That is, we allow equality in stopping tests when the
05461  *         round-nearest rule will give the same floating-point value
05462  *         as would satisfaction of the stopping test with strict
05463  *         inequality.
05464  *      4. We remove common factors of powers of 2 from relevant
05465  *         quantities.
05466  *      5. When converting floating-point integers less than 1e16,
05467  *         we use floating-point arithmetic rather than resorting
05468  *         to multiple-precision integers.
05469  *      6. When asked to produce fewer than 15 digits, we first try
05470  *         to get by with floating-point arithmetic; we resort to
05471  *         multiple-precision integer arithmetic only if we cannot
05472  *         guarantee that the floating-point calculation has given
05473  *         the correctly rounded result.  For k requested digits and
05474  *         "uniformly" distributed input, the probability is
05475  *         something like 10^(k-15) that we must resort to the Long
05476  *         calculation.
05477  */
05478 
05479 
05480 /* This actually sometimes returns a pointer to a string literal
05481    cast to a char*. Do NOT try to modify the return value. */
05482 
05483 static char *qdtoa (volatile double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
05484 {
05485     /*
05486       Arguments ndigits, decpt, sign are similar to those
05487       of ecvt and fcvt; trailing zeros are suppressed from
05488       the returned string.  If not null, *rve is set to point
05489       to the end of the return value.  If d is +-Infinity or NaN,
05490       then *decpt is set to 9999.
05491 
05492       mode:
05493       0 ==> shortest string that yields d when read in
05494       and rounded to nearest.
05495       1 ==> like 0, but with Steele & White stopping rule;
05496       e.g. with IEEE P754 arithmetic , mode 0 gives
05497       1e23 whereas mode 1 gives 9.999999999999999e22.
05498       2 ==> max(1,ndigits) significant digits.  This gives a
05499       return value similar to that of ecvt, except
05500       that trailing zeros are suppressed.
05501       3 ==> through ndigits past the decimal point.  This
05502       gives a return value similar to that from fcvt,
05503       except that trailing zeros are suppressed, and
05504       ndigits can be negative.
05505       4-9 should give the same return values as 2-3, i.e.,
05506       4 <= mode <= 9 ==> same return as mode
05507       2 + (mode & 1).  These modes are mainly for
05508       debugging; often they run slower but sometimes
05509       faster than modes 2-3.
05510       4,5,8,9 ==> left-to-right digit generation.
05511       6-9 ==> don't try fast floating-point estimate
05512       (if applicable).
05513 
05514       Values of mode other than 0-9 are treated as mode 0.
05515 
05516       Sufficient space is allocated to the return value
05517       to hold the suppressed trailing zeros.
05518     */
05519 
05520     int bbits, b2, b5, be, dig, i, ieps, ilim0,
05521         j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
05522         try_quick;
05523     int ilim = 0, ilim1 = 0, spec_case = 0;     /* pacify gcc */
05524     Long L;
05525 #ifndef Sudden_Underflow
05526     int denorm;
05527     ULong x;
05528 #endif
05529     Bigint *b, *b1, *delta, *mhi, *S;
05530     Bigint *mlo = NULL; /* pacify gcc */
05531     volatile double d2;
05532     double ds, eps;
05533     char *s, *s0;
05534 
05535     if (word0(d) & Sign_bit) {
05536         /* set sign for everything, including 0's and NaNs */
05537         *sign = 1;
05538         word0(d) &= ~Sign_bit;  /* clear sign bit */
05539     }
05540     else
05541         *sign = 0;
05542 
05543 #if defined(IEEE_Arith) + defined(VAX)
05544 #ifdef IEEE_Arith
05545     if ((word0(d) & Exp_mask) == Exp_mask)
05546 #else
05547         if (word0(d)  == 0x8000)
05548 #endif
05549             {
05550                 /* Infinity or NaN */
05551                 *decpt = 9999;
05552                 s =
05553 #ifdef IEEE_Arith
05554                     !word1(d) && !(word0(d) & 0xfffff) ? (char*)"Infinity" :
05555 #endif
05556                     (char*)"NaN";
05557                 if (rve)
05558                     *rve =
05559 #ifdef IEEE_Arith
05560                         s[3] ? s + 8 :
05561 #endif
05562                         s + 3;
05563                 return s;
05564             }
05565 #endif
05566 #ifdef IBM
05567     d += 0; /* normalize */
05568 #endif
05569     if (d == g_double_zero)
05570         {
05571             *decpt = 1;
05572             s = (char*) "0";
05573             if (rve)
05574                 *rve = s + 1;
05575             return s;
05576         }
05577 
05578     b = d2b(d, &be, &bbits);
05579 #ifdef Sudden_Underflow
05580     i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
05581 #else
05582     if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
05583 #endif
05584         d2 = d;
05585         word0(d2) &= Frac_mask1;
05586         word0(d2) |= Exp_11;
05587 #ifdef IBM
05588         if (j = 11 - hi0bits(word0(d2) & Frac_mask))
05589             d2 /= 1 << j;
05590 #endif
05591 
05592         /* log(x)       ~=~ log(1.5) + (x-1.5)/1.5
05593          * log10(x)      =  log(x) / log(10)
05594          *              ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
05595          * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
05596          *
05597          * This suggests computing an approximation k to log10(d) by
05598          *
05599          * k = (i - Bias)*0.301029995663981
05600          *      + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
05601          *
05602          * We want k to be too large rather than too small.
05603          * The error in the first-order Taylor series approximation
05604          * is in our favor, so we just round up the constant enough
05605          * to compensate for any error in the multiplication of
05606          * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
05607          * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
05608          * adding 1e-13 to the constant term more than suffices.
05609          * Hence we adjust the constant term to 0.1760912590558.
05610          * (We could get a more accurate k by invoking log10,
05611          *  but this is probably not worthwhile.)
05612          */
05613 
05614         i -= Bias;
05615 #ifdef IBM
05616         i <<= 2;
05617         i += j;
05618 #endif
05619 #ifndef Sudden_Underflow
05620         denorm = 0;
05621     }
05622     else {
05623         /* d is denormalized */
05624 
05625         i = bbits + be + (Bias + (P-1) - 1);
05626         x = i > 32  ? word0(d) << (64 - i) | word1(d) >> (i - 32)
05627             : word1(d) << (32 - i);
05628         d2 = x;
05629         word0(d2) -= 31*Exp_msk1; /* adjust exponent */
05630         i -= (Bias + (P-1) - 1) + 1;
05631         denorm = 1;
05632     }
05633 #endif
05634     ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
05635     k = (int)ds;
05636     if (ds < 0. && ds != k)
05637         k--;    /* want k = floor(ds) */
05638     k_check = 1;
05639     if (k >= 0 && k <= Ten_pmax) {
05640         if (d < tens[k])
05641             k--;
05642         k_check = 0;
05643     }
05644     j = bbits - i - 1;
05645     if (j >= 0) {
05646         b2 = 0;
05647         s2 = j;
05648     }
05649     else {
05650         b2 = -j;
05651         s2 = 0;
05652     }
05653     if (k >= 0) {
05654         b5 = 0;
05655         s5 = k;
05656         s2 += k;
05657     }
05658     else {
05659         b2 -= k;
05660         b5 = -k;
05661         s5 = 0;
05662     }
05663     if (mode < 0 || mode > 9)
05664         mode = 0;
05665     try_quick = 1;
05666     if (mode > 5) {
05667         mode -= 4;
05668         try_quick = 0;
05669     }
05670     leftright = 1;
05671     switch(mode) {
05672     case 0:
05673     case 1:
05674         ilim = ilim1 = -1;
05675         i = 18;
05676         ndigits = 0;
05677         break;
05678     case 2:
05679         leftright = 0;
05680         /* no break */
05681     case 4:
05682         if (ndigits <= 0)
05683             ndigits = 1;
05684         ilim = ilim1 = i = ndigits;
05685         break;
05686     case 3:
05687         leftright = 0;
05688         /* no break */
05689     case 5:
05690         i = ndigits + k + 1;
05691         ilim = i;
05692         ilim1 = i - 1;
05693         if (i <= 0)
05694             i = 1;
05695     }
05696     *resultp = (char *) malloc(i + 1);
05697     s = s0 = *resultp;
05698 
05699     if (ilim >= 0 && ilim <= Quick_max && try_quick) {
05700 
05701         /* Try to get by with floating-point arithmetic. */
05702 
05703         i = 0;
05704         d2 = d;
05705         k0 = k;
05706         ilim0 = ilim;
05707         ieps = 2; /* conservative */
05708         if (k > 0) {
05709             ds = tens[k&0xf];
05710             j = k >> 4;
05711             if (j & Bletch) {
05712                 /* prevent overflows */
05713                 j &= Bletch - 1;
05714                 d /= bigtens[n_bigtens-1];
05715                 ieps++;
05716             }
05717             for(; j; j >>= 1, i++)
05718                 if (j & 1) {
05719                     ieps++;
05720                     ds *= bigtens[i];
05721                 }
05722             d /= ds;
05723         }
05724         else if ((j1 = -k) != 0) {
05725             d *= tens[j1 & 0xf];
05726             for(j = j1 >> 4; j; j >>= 1, i++)
05727                 if (j & 1) {
05728                     ieps++;
05729                     d *= bigtens[i];
05730                 }
05731         }
05732         if (k_check && d < 1. && ilim > 0) {
05733             if (ilim1 <= 0)
05734                 goto fast_failed;
05735             ilim = ilim1;
05736             k--;
05737             d *= 10.;
05738             ieps++;
05739         }
05740         eps = ieps*d + 7.;
05741         word0(eps) -= (P-1)*Exp_msk1;
05742         if (ilim == 0) {
05743             S = mhi = 0;
05744             d -= 5.;
05745             if (d > eps)
05746                 goto one_digit;
05747             if (d < -eps)
05748                 goto no_digits;
05749             goto fast_failed;
05750         }
05751 #ifndef No_leftright
05752         if (leftright) {
05753             /* Use Steele & White method of only
05754              * generating digits needed.
05755              */
05756             eps = 0.5/tens[ilim-1] - eps;
05757             for(i = 0;;) {
05758                 L = (Long)d;
05759                 d -= L;
05760                 *s++ = '0' + (int)L;
05761                 if (d < eps)
05762                     goto ret1;
05763                 if (1. - d < eps)
05764                     goto bump_up;
05765                 if (++i >= ilim)
05766                     break;
05767                 eps *= 10.;
05768                 d *= 10.;
05769             }
05770         }
05771         else {
05772 #endif
05773             /* Generate ilim digits, then fix them up. */
05774             eps *= tens[ilim-1];
05775             for(i = 1;; i++, d *= 10.) {
05776                 L = (Long)d;
05777                 d -= L;
05778                 *s++ = '0' + (int)L;
05779                 if (i == ilim) {
05780                     if (d > 0.5 + eps)
05781                         goto bump_up;
05782                     else if (d < 0.5 - eps) {
05783                         while(*--s == '0');
05784                         s++;
05785                         goto ret1;
05786                     }
05787                     break;
05788                 }
05789             }
05790 #ifndef No_leftright
05791         }
05792 #endif
05793     fast_failed:
05794         s = s0;
05795         d = d2;
05796         k = k0;
05797         ilim = ilim0;
05798     }
05799 
05800     /* Do we have a "small" integer? */
05801 
05802     if (be >= 0 && k <= Int_max) {
05803         /* Yes. */
05804         ds = tens[k];
05805         if (ndigits < 0 && ilim <= 0) {
05806             S = mhi = 0;
05807             if (ilim < 0 || d <= 5*ds)
05808                 goto no_digits;
05809             goto one_digit;
05810         }
05811         for(i = 1;; i++) {
05812             L = (Long)(d / ds);
05813             d -= L*ds;
05814 #ifdef Check_FLT_ROUNDS
05815             /* If FLT_ROUNDS == 2, L will usually be high by 1 */
05816             if (d < 0) {
05817                 L--;
05818                 d += ds;
05819             }
05820 #endif
05821             *s++ = '0' + (int)L;
05822             if (i == ilim) {
05823                 d += d;
05824                 if (d > ds || (d == ds && L & 1)) {
05825                 bump_up:
05826                     while(*--s == '9')
05827                         if (s == s0) {
05828                             k++;
05829                             *s = '0';
05830                             break;
05831                         }
05832                     ++*s++;
05833                 }
05834                 break;
05835             }
05836             if ((d *= 10.) == g_double_zero)
05837                 break;
05838         }
05839         goto ret1;
05840     }
05841 
05842     m2 = b2;
05843     m5 = b5;
05844     mhi = mlo = 0;
05845     if (leftright) {
05846         if (mode < 2) {
05847             i =
05848 #ifndef Sudden_Underflow
05849                 denorm ? be + (Bias + (P-1) - 1 + 1) :
05850 #endif
05851 #ifdef IBM
05852                 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
05853 #else
05854             1 + P - bbits;
05855 #endif
05856         }
05857         else {
05858             j = ilim - 1;
05859             if (m5 >= j)
05860                 m5 -= j;
05861             else {
05862                 s5 += j -= m5;
05863                 b5 += j;
05864                 m5 = 0;
05865             }
05866             if ((i = ilim) < 0) {
05867                 m2 -= i;
05868                 i = 0;
05869             }
05870         }
05871         b2 += i;
05872         s2 += i;
05873         mhi = i2b(1);
05874     }
05875     if (m2 > 0 && s2 > 0) {
05876         i = m2 < s2 ? m2 : s2;
05877         b2 -= i;
05878         m2 -= i;
05879         s2 -= i;
05880     }
05881     if (b5 > 0) {
05882         if (leftright) {
05883             if (m5 > 0) {
05884                 mhi = pow5mult(mhi, m5);
05885                 b1 = mult(mhi, b);
05886                 Bfree(b);
05887                 b = b1;
05888             }
05889             if ((j = b5 - m5) != 0)
05890                 b = pow5mult(b, j);
05891         }
05892         else
05893             b = pow5mult(b, b5);
05894     }
05895     S = i2b(1);
05896     if (s5 > 0)
05897         S = pow5mult(S, s5);
05898 
05899     /* Check for special case that d is a normalized power of 2. */
05900 
05901     if (mode < 2) {
05902         if (!word1(d) && !(word0(d) & Bndry_mask)
05903 #ifndef Sudden_Underflow
05904             && word0(d) & Exp_mask
05905 #endif
05906             ) {
05907             /* The special case */
05908             b2 += Log2P;
05909             s2 += Log2P;
05910             spec_case = 1;
05911         }
05912         else
05913             spec_case = 0;
05914     }
05915 
05916     /* Arrange for convenient computation of quotients:
05917      * shift left if necessary so divisor has 4 leading 0 bits.
05918      *
05919      * Perhaps we should just compute leading 28 bits of S once
05920      * and for all and pass them and a shift to quorem, so it
05921      * can do shifts and ors to compute the numerator for q.
05922      */
05923 #ifdef Pack_32
05924     if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
05925         i = 32 - i;
05926 #else
05927     if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
05928         i = 16 - i;
05929 #endif
05930     if (i > 4) {
05931         i -= 4;
05932         b2 += i;
05933         m2 += i;
05934         s2 += i;
05935     }
05936     else if (i < 4) {
05937         i += 28;
05938         b2 += i;
05939         m2 += i;
05940         s2 += i;
05941     }
05942     if (b2 > 0)
05943         b = lshift(b, b2);
05944     if (s2 > 0)
05945         S = lshift(S, s2);
05946     if (k_check) {
05947         if (cmp(b,S) < 0) {
05948             k--;
05949             b = multadd(b, 10, 0);      /* we botched the k estimate */
05950             if (leftright)
05951                 mhi = multadd(mhi, 10, 0);
05952             ilim = ilim1;
05953         }
05954     }
05955     if (ilim <= 0 && mode > 2) {
05956         if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
05957             /* no digits, fcvt style */
05958         no_digits:
05959             k = -1 - ndigits;
05960             goto ret;
05961         }
05962     one_digit:
05963         *s++ = '1';
05964         k++;
05965         goto ret;
05966     }
05967     if (leftright) {
05968         if (m2 > 0)
05969             mhi = lshift(mhi, m2);
05970 
05971         /* Compute mlo -- check for special case
05972          * that d is a normalized power of 2.
05973          */
05974 
05975         mlo = mhi;
05976         if (spec_case) {
05977             mhi = Balloc(mhi->k);
05978             Bcopy(mhi, mlo);
05979             mhi = lshift(mhi, Log2P);
05980         }
05981 
05982         for(i = 1;;i++) {
05983             dig = quorem(b,S) + '0';
05984             /* Do we yet have the shortest decimal string
05985              * that will round to d?
05986              */
05987             j = cmp(b, mlo);
05988             delta = diff(S, mhi);
05989             j1 = delta->sign ? 1 : cmp(b, delta);
05990             Bfree(delta);
05991 #ifndef ROUND_BIASED
05992             if (j1 == 0 && !mode && !(word1(d) & 1)) {
05993                 if (dig == '9')
05994                     goto round_9_up;
05995                 if (j > 0)
05996                     dig++;
05997                 *s++ = dig;
05998                 goto ret;
05999             }
06000 #endif
06001             if (j < 0 || (j == 0 && !mode
06002 #ifndef ROUND_BIASED
06003                           && !(word1(d) & 1)
06004 #endif
06005                           )) {
06006                 if (j1 > 0) {
06007                     b = lshift(b, 1);
06008                     j1 = cmp(b, S);
06009                     if ((j1 > 0 || (j1 == 0 && dig & 1))
06010                         && dig++ == '9')
06011                         goto round_9_up;
06012                 }
06013                 *s++ = dig;
06014                 goto ret;
06015             }
06016             if (j1 > 0) {
06017                 if (dig == '9') { /* possible if i == 1 */
06018                 round_9_up:
06019                     *s++ = '9';
06020                     goto roundoff;
06021                 }
06022                 *s++ = dig + 1;
06023                 goto ret;
06024             }
06025             *s++ = dig;
06026             if (i == ilim)
06027                 break;
06028             b = multadd(b, 10, 0);
06029             if (mlo == mhi)
06030                 mlo = mhi = multadd(mhi, 10, 0);
06031             else {
06032                 mlo = multadd(mlo, 10, 0);
06033                 mhi = multadd(mhi, 10, 0);
06034             }
06035         }
06036     }
06037     else
06038         for(i = 1;; i++) {
06039             *s++ = dig = quorem(b,S) + '0';
06040             if (i >= ilim)
06041                 break;
06042             b = multadd(b, 10, 0);
06043         }
06044 
06045     /* Round off last digit */
06046 
06047     b = lshift(b, 1);
06048     j = cmp(b, S);
06049     if (j > 0 || (j == 0 && dig & 1)) {
06050     roundoff:
06051         while(*--s == '9')
06052             if (s == s0) {
06053                 k++;
06054                 *s++ = '1';
06055                 goto ret;
06056             }
06057         ++*s++;
06058     }
06059     else {
06060         while(*--s == '0');
06061         s++;
06062     }
06063  ret:
06064     Bfree(S);
06065     if (mhi) {
06066         if (mlo && mlo != mhi)
06067             Bfree(mlo);
06068         Bfree(mhi);
06069     }
06070  ret1:
06071     Bfree(b);
06072     if (s == s0) {                              /* don't return empty string */
06073         *s++ = '0';
06074         k = 0;
06075     }
06076     *s = 0;
06077     *decpt = k + 1;
06078     if (rve)
06079         *rve = s;
06080     return s0;
06081 }
06082 
06083 #endif // QT_QLOCALE_USES_FCVT

Generated on Sat Nov 5 16:18:31 2005 for OPIE by  doxygen 1.4.2