00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
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
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,
00138 0,
00139 0,
00140 0,
00141 0,
00142 1,
00143 2,
00144 0,
00145 3,
00146 19,
00147 0,
00148 0,
00149 20,
00150 0,
00151 21,
00152 0,
00153 0,
00154 0,
00155 0,
00156 0,
00157 22,
00158 0,
00159 23,
00160 0,
00161 24,
00162 25,
00163 0,
00164 30,
00165 31,
00166 32,
00167 33,
00168 35,
00169 0,
00170 47,
00171 48,
00172 0,
00173 49,
00174 50,
00175 0,
00176 0,
00177 56,
00178 57,
00179 58,
00180 63,
00181 0,
00182 0,
00183 64,
00184 0,
00185 65,
00186 66,
00187 67,
00188 68,
00189 69,
00190 0,
00191 0,
00192 0,
00193 0,
00194 0,
00195 70,
00196 72,
00197 0,
00198 73,
00199 0,
00200 74,
00201 0,
00202 75,
00203 76,
00204 0,
00205 0,
00206 0,
00207 0,
00208 77,
00209 0,
00210 78,
00211 79,
00212 0,
00213 80,
00214 0,
00215 0,
00216 0,
00217 82,
00218 0,
00219 83,
00220 0,
00221 0,
00222 84,
00223 0,
00224 0,
00225 0,
00226 85,
00227 86,
00228 87,
00229 89,
00230 0,
00231 0,
00232 90,
00233 91,
00234 0,
00235 0,
00236 92,
00237 0,
00238 0,
00239 0,
00240 0,
00241 0,
00242 0,
00243 0,
00244 0,
00245 93,
00246 94,
00247 0,
00248 95,
00249 0,
00250 114,
00251 115,
00252 0,
00253 0,
00254 117,
00255 0,
00256 118,
00257 119,
00258 0,
00259 0,
00260 0,
00261 0,
00262 120,
00263 0,
00264 0,
00265 0,
00266 121,
00267 122,
00268 123,
00269 124,
00270 0,
00271 0,
00272 0,
00273 0,
00274 0,
00275 0,
00276 0,
00277 0,
00278 0
00279 };
00280
00281 static const QLocalePrivate locale_data[] = {
00282
00283 { 1, 0, 46, 44, 59, 37, 48, 45, 101 },
00284 { 5, 195, 46, 44, 44, 37, 48, 45, 101 },
00285 { 6, 2, 44, 46, 59, 37, 48, 45, 101 },
00286 { 8, 186, 46, 44, 59, 37, 1632, 45, 101 },
00287 { 8, 3, 46, 44, 59, 37, 48, 45, 101 },
00288 { 8, 17, 46, 44, 59, 37, 1632, 45, 101 },
00289 { 8, 64, 46, 44, 59, 37, 1632, 45, 101 },
00290 { 8, 103, 46, 44, 59, 37, 1632, 45, 101 },
00291 { 8, 109, 46, 44, 59, 37, 1632, 45, 101 },
00292 { 8, 115, 46, 44, 59, 37, 1632, 45, 101 },
00293 { 8, 119, 46, 44, 59, 37, 1632, 45, 101 },
00294 { 8, 122, 46, 44, 59, 37, 48, 45, 101 },
00295 { 8, 145, 46, 44, 59, 37, 48, 45, 101 },
00296 { 8, 162, 46, 44, 59, 37, 1632, 45, 101 },
00297 { 8, 175, 46, 44, 59, 37, 1632, 45, 101 },
00298 { 8, 207, 46, 44, 59, 37, 1632, 45, 101 },
00299 { 8, 216, 46, 44, 59, 37, 48, 45, 101 },
00300 { 8, 223, 46, 44, 59, 37, 1632, 45, 101 },
00301 { 8, 237, 46, 44, 59, 37, 1632, 45, 101 },
00302 { 9, 11, 46, 44, 44, 37, 48, 45, 101 },
00303 { 12, 15, 44, 160, 59, 37, 48, 45, 101 },
00304 { 14, 197, 44, 46, 59, 37, 48, 45, 101 },
00305 { 20, 33, 44, 160, 59, 37, 48, 45, 101 },
00306 { 22, 20, 44, 160, 59, 37, 48, 45, 101 },
00307 { 24, 197, 44, 46, 59, 37, 48, 45, 101 },
00308 { 25, 44, 46, 44, 44, 37, 48, 45, 101 },
00309 { 25, 97, 46, 44, 44, 37, 48, 45, 101 },
00310 { 25, 126, 46, 44, 44, 37, 48, 45, 101 },
00311 { 25, 190, 46, 44, 44, 37, 48, 45, 101 },
00312 { 25, 208, 46, 44, 44, 37, 48, 45, 101 },
00313 { 27, 54, 44, 46, 59, 37, 48, 45, 101 },
00314 { 28, 57, 44, 160, 59, 37, 48, 45, 101 },
00315 { 29, 58, 44, 46, 59, 37, 48, 45, 101 },
00316 { 30, 151, 44, 46, 59, 37, 48, 45, 101 },
00317 { 30, 21, 44, 46, 59, 37, 48, 45, 101 },
00318 { 31, 225, 46, 44, 44, 37, 48, 45, 101 },
00319 { 31, 13, 46, 44, 44, 37, 48, 45, 101 },
00320 { 31, 22, 46, 44, 59, 37, 48, 45, 101 },
00321 { 31, 38, 46, 44, 44, 37, 48, 45, 101 },
00322 { 31, 104, 46, 44, 44, 37, 48, 45, 101 },
00323 { 31, 107, 46, 44, 44, 37, 48, 45, 101 },
00324 { 31, 154, 46, 44, 44, 37, 48, 45, 101 },
00325 { 31, 170, 46, 44, 44, 37, 48, 45, 101 },
00326 { 31, 195, 46, 44, 44, 37, 48, 45, 101 },
00327 { 31, 215, 46, 44, 59, 37, 48, 45, 101 },
00328 { 31, 224, 46, 44, 44, 37, 48, 45, 101 },
00329 { 31, 240, 46, 44, 44, 37, 48, 45, 101 },
00330 { 33, 68, 44, 160, 59, 37, 48, 45, 101 },
00331 { 34, 71, 44, 46, 59, 37, 48, 45, 101 },
00332 { 36, 73, 44, 160, 59, 37, 48, 45, 101 },
00333 { 37, 74, 44, 160, 59, 37, 48, 45, 101 },
00334 { 37, 21, 44, 46, 59, 37, 48, 45, 101 },
00335 { 37, 38, 44, 160, 59, 37, 48, 45, 101 },
00336 { 37, 125, 44, 160, 59, 37, 48, 45, 101 },
00337 { 37, 142, 44, 160, 59, 37, 48, 45, 101 },
00338 { 37, 206, 46, 39, 59, 37, 48, 45, 101 },
00339 { 40, 197, 44, 46, 44, 37, 48, 45, 101 },
00340 { 41, 81, 44, 160, 59, 37, 48, 45, 101 },
00341 { 42, 82, 44, 46, 59, 37, 48, 45, 101 },
00342 { 42, 14, 44, 46, 59, 37, 48, 45, 101 },
00343 { 42, 123, 46, 39, 59, 37, 48, 45, 101 },
00344 { 42, 125, 44, 46, 59, 37, 48, 45, 101 },
00345 { 42, 206, 46, 39, 59, 37, 48, 45, 101 },
00346 { 43, 85, 44, 46, 59, 37, 48, 45, 101 },
00347 { 46, 100, 46, 44, 44, 37, 2790, 45, 101 },
00348 { 48, 105, 46, 44, 44, 37, 48, 45, 101 },
00349 { 49, 100, 46, 44, 44, 37, 48, 45, 101 },
00350 { 50, 98, 44, 160, 59, 37, 48, 45, 101 },
00351 { 51, 99, 44, 46, 59, 37, 48, 45, 101 },
00352 { 52, 101, 44, 46, 59, 37, 48, 45, 101 },
00353 { 58, 106, 44, 46, 59, 37, 48, 45, 101 },
00354 { 58, 206, 46, 39, 59, 37, 48, 45, 101 },
00355 { 59, 108, 46, 44, 44, 37, 48, 45, 101 },
00356 { 61, 100, 46, 44, 44, 37, 3302, 45, 101 },
00357 { 63, 110, 44, 160, 59, 37, 48, 45, 101 },
00358 { 65, 116, 44, 160, 59, 37, 48, 45, 101 },
00359 { 66, 114, 46, 44, 44, 37, 48, 45, 101 },
00360 { 71, 118, 44, 160, 59, 37, 48, 45, 101 },
00361 { 73, 124, 44, 46, 59, 37, 48, 45, 101 },
00362 { 74, 127, 44, 46, 59, 37, 48, 45, 101 },
00363 { 76, 130, 44, 46, 59, 37, 48, 45, 101 },
00364 { 76, 32, 44, 46, 59, 37, 48, 45, 101 },
00365 { 80, 100, 46, 44, 44, 37, 2406, 45, 101 },
00366 { 82, 143, 44, 160, 59, 37, 48, 45, 101 },
00367 { 85, 161, 44, 160, 59, 37, 48, 45, 101 },
00368 { 89, 102, 46, 44, 59, 37, 1776, 45, 101 },
00369 { 90, 172, 44, 160, 59, 37, 48, 45, 101 },
00370 { 91, 173, 44, 46, 59, 37, 48, 45, 101 },
00371 { 91, 30, 44, 46, 59, 37, 48, 45, 101 },
00372 { 92, 100, 46, 44, 44, 37, 2662, 45, 101 },
00373 { 95, 177, 44, 46, 59, 37, 48, 45, 101 },
00374 { 96, 178, 44, 160, 59, 37, 48, 45, 101 },
00375 { 99, 100, 46, 44, 44, 37, 2406, 45, 101 },
00376 { 108, 191, 44, 160, 59, 37, 48, 45, 101 },
00377 { 109, 192, 44, 46, 59, 37, 48, 45, 101 },
00378 { 111, 197, 44, 46, 59, 37, 48, 45, 101 },
00379 { 111, 10, 44, 46, 44, 37, 48, 45, 101 },
00380 { 111, 26, 44, 46, 44, 37, 48, 45, 101 },
00381 { 111, 43, 44, 46, 44, 37, 48, 45, 101 },
00382 { 111, 47, 44, 46, 44, 37, 48, 45, 101 },
00383 { 111, 52, 44, 46, 44, 37, 48, 45, 101 },
00384 { 111, 61, 46, 44, 44, 37, 48, 45, 101 },
00385 { 111, 63, 44, 46, 44, 37, 48, 45, 101 },
00386 { 111, 65, 46, 44, 44, 37, 48, 45, 101 },
00387 { 111, 90, 46, 44, 44, 37, 48, 45, 101 },
00388 { 111, 96, 46, 44, 44, 37, 48, 45, 101 },
00389 { 111, 139, 46, 44, 44, 37, 48, 45, 101 },
00390 { 111, 155, 46, 44, 44, 37, 48, 45, 101 },
00391 { 111, 166, 46, 44, 44, 37, 48, 45, 101 },
00392 { 111, 168, 44, 46, 44, 37, 48, 45, 101 },
00393 { 111, 169, 46, 44, 44, 37, 48, 45, 101 },
00394 { 111, 174, 46, 44, 44, 37, 48, 45, 101 },
00395 { 111, 227, 44, 46, 44, 37, 48, 45, 101 },
00396 { 111, 231, 44, 46, 44, 37, 48, 45, 101 },
00397 { 113, 111, 46, 44, 44, 37, 48, 45, 101 },
00398 { 114, 205, 44, 160, 59, 37, 48, 45, 101 },
00399 { 114, 73, 44, 160, 59, 37, 48, 45, 101 },
00400 { 117, 100, 46, 44, 44, 37, 48, 45, 101 },
00401 { 119, 100, 46, 44, 44, 37, 3174, 45, 101 },
00402 { 120, 211, 46, 44, 44, 37, 3664, 45, 101 },
00403 { 125, 217, 44, 46, 59, 37, 48, 45, 101 },
00404 { 129, 222, 44, 160, 59, 37, 48, 45, 101 },
00405 { 130, 163, 46, 44, 59, 37, 1776, 45, 101 },
00406 { 131, 228, 44, 160, 59, 37, 48, 45, 101 },
00407 { 132, 232, 44, 46, 44, 37, 48, 45, 101 },
00408 { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
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,
00556 8,
00557 10,
00558 20,
00559 25,
00560 30,
00561 40,
00562 49,
00563 57,
00564 64,
00565 73,
00566 82,
00567 89,
00568 101,
00569 109,
00570 116,
00571 124,
00572 132,
00573 139,
00574 147,
00575 154,
00576 164,
00577 172,
00578 185,
00579 195,
00580 203,
00581 211,
00582 220,
00583 229,
00584 235,
00585 242,
00586 248,
00587 256,
00588 266,
00589 275,
00590 283,
00591 288,
00592 296,
00593 303,
00594 311,
00595 318,
00596 327,
00597 336,
00598 343,
00599 349,
00600 361,
00601 369,
00602 378,
00603 384,
00604 391,
00605 397,
00606 407,
00607 417,
00608 428,
00609 440,
00610 452,
00611 462,
00612 470,
00613 476,
00614 484,
00615 493,
00616 502,
00617 510,
00618 519,
00619 526,
00620 538,
00621 546,
00622 553,
00623 561,
00624 569,
00625 578,
00626 584,
00627 592,
00628 600,
00629 611,
00630 622,
00631 631,
00632 637,
00633 647,
00634 655,
00635 661,
00636 669,
00637 679,
00638 689,
00639 695,
00640 702,
00641 712,
00642 720,
00643 726,
00644 733,
00645 741,
00646 748,
00647 759,
00648 767,
00649 775,
00650 789,
00651 798,
00652 806,
00653 813,
00654 820,
00655 829,
00656 837,
00657 851,
00658 859,
00659 868,
00660 874,
00661 881,
00662 892,
00663 900,
00664 907,
00665 917,
00666 924,
00667 932,
00668 942,
00669 950,
00670 958,
00671 966,
00672 972,
00673 978,
00674 984,
00675 991,
00676 996,
00677 1004,
00678 1013,
00679 1019,
00680 1026,
00681 1034,
00682 1042,
00683 1046,
00684 1052,
00685 1062,
00686 1067,
00687 1073,
00688 1084,
00689 1092,
00690 1098,
00691 1104,
00692 1110,
00693 1118,
00694 1125,
00695 1132
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,
00943 8,
00944 20,
00945 28,
00946 36,
00947 50,
00948 58,
00949 65,
00950 74,
00951 85,
00952 103,
00953 113,
00954 121,
00955 127,
00956 137,
00957 145,
00958 156,
00959 164,
00960 172,
00961 183,
00962 192,
00963 200,
00964 208,
00965 215,
00966 221,
00967 229,
00968 236,
00969 244,
00970 265,
00971 274,
00972 287,
00973 294,
00974 322,
00975 339,
00976 348,
00977 360,
00978 368,
00979 377,
00980 386,
00981 393,
00982 403,
00983 417,
00984 440,
00985 445,
00986 451,
00987 457,
00988 473,
00989 486,
00990 495,
00991 503,
00992 529,
00993 552,
00994 564,
00995 574,
00996 585,
00997 593,
00998 598,
00999 605,
01000 619,
01001 627,
01002 636,
01003 645,
01004 663,
01005 673,
01006 681,
01007 687,
01008 698,
01009 715,
01010 723,
01011 731,
01012 740,
01013 756,
01014 769,
01015 774,
01016 782,
01017 789,
01018 808,
01019 821,
01020 837,
01021 863,
01022 869,
01023 876,
01024 884,
01025 892,
01026 898,
01027 908,
01028 915,
01029 925,
01030 933,
01031 944,
01032 949,
01033 959,
01034 966,
01035 979,
01036 986,
01037 992,
01038 1016,
01039 1025,
01040 1034,
01041 1042,
01042 1050,
01043 1056,
01044 1066,
01045 1071,
01046 1076,
01047 1084,
01048 1091,
01049 1097,
01050 1105,
01051 1111,
01052 1118,
01053 1129,
01054 1135,
01055 1144,
01056 1170,
01057 1186,
01058 1193,
01059 1204,
01060 1208,
01061 1215,
01062 1223,
01063 1231,
01064 1239,
01065 1260,
01066 1274,
01067 1284,
01068 1295,
01069 1301,
01070 1311,
01071 1322,
01072 1329,
01073 1338,
01074 1347,
01075 1352,
01076 1358,
01077 1374,
01078 1385,
01079 1396,
01080 1406,
01081 1414,
01082 1421,
01083 1432,
01084 1440,
01085 1447,
01086 1456,
01087 1467,
01088 1475,
01089 1486,
01090 1494,
01091 1502,
01092 1508,
01093 1514,
01094 1526,
01095 1546,
01096 1559,
01097 1570,
01098 1580,
01099 1586,
01100 1594,
01101 1599,
01102 1613,
01103 1636,
01104 1643,
01105 1648,
01106 1657,
01107 1663,
01108 1684,
01109 1691,
01110 1706,
01111 1715,
01112 1720,
01113 1732,
01114 1741,
01115 1748,
01116 1757,
01117 1768,
01118 1774,
01119 1782,
01120 1790,
01121 1808,
01122 1815,
01123 1834,
01124 1842,
01125 1868,
01126 1874,
01127 1884,
01128 1903,
01129 1915,
01130 1923,
01131 1934,
01132 1946,
01133 1956,
01134 1965,
01135 1974,
01136 1989,
01137 1997,
01138 2009,
01139 2048,
01140 2054,
01141 2063,
01142 2072,
01143 2092,
01144 2098,
01145 2107,
01146 2134,
01147 2144,
01148 2151,
01149 2163,
01150 2182,
01151 2189,
01152 2200,
01153 2209,
01154 2218,
01155 2223,
01156 2231,
01157 2237,
01158 2255,
01159 2263,
01160 2270,
01161 2283,
01162 2305,
01163 2312,
01164 2319,
01165 2327,
01166 2346,
01167 2360,
01168 2373,
01169 2406,
01170 2414,
01171 2425,
01172 2433,
01173 2450,
01174 2460,
01175 2468,
01176 2489,
01177 2505,
01178 2528,
01179 2542,
01180 2548,
01181 2559,
01182 2566
01183 };
01184
01185 static const char language_code_list[] =
01186 " "
01187 " "
01188 "ab"
01189 "om"
01190 "aa"
01191 "af"
01192 "sq"
01193 "am"
01194 "ar"
01195 "hy"
01196 "as"
01197 "ay"
01198 "az"
01199 "ba"
01200 "eu"
01201 "bn"
01202 "dz"
01203 "bh"
01204 "bi"
01205 "br"
01206 "bg"
01207 "my"
01208 "be"
01209 "km"
01210 "ca"
01211 "zh"
01212 "co"
01213 "hr"
01214 "cs"
01215 "da"
01216 "nl"
01217 "en"
01218 "eo"
01219 "et"
01220 "fo"
01221 "fj"
01222 "fi"
01223 "fr"
01224 "fy"
01225 "gd"
01226 "gl"
01227 "ka"
01228 "de"
01229 "el"
01230 "kl"
01231 "gn"
01232 "gu"
01233 "ha"
01234 "he"
01235 "hi"
01236 "hu"
01237 "is"
01238 "id"
01239 "ia"
01240 "ie"
01241 "iu"
01242 "ik"
01243 "ga"
01244 "it"
01245 "ja"
01246 "jv"
01247 "kn"
01248 "ks"
01249 "kk"
01250 "rw"
01251 "ky"
01252 "ko"
01253 "ku"
01254 "rn"
01255 "lo"
01256 "la"
01257 "lv"
01258 "ln"
01259 "lt"
01260 "mk"
01261 "mg"
01262 "ms"
01263 "ml"
01264 "mt"
01265 "mi"
01266 "mr"
01267 "mo"
01268 "mn"
01269 "na"
01270 "ne"
01271 "no"
01272 "oc"
01273 "or"
01274 "ps"
01275 "fa"
01276 "pl"
01277 "pt"
01278 "pa"
01279 "qu"
01280 "rm"
01281 "ro"
01282 "ru"
01283 "sm"
01284 "sg"
01285 "sa"
01286 "sr"
01287 "sh"
01288 "st"
01289 "tn"
01290 "sn"
01291 "sd"
01292 "si"
01293 "ss"
01294 "sk"
01295 "sl"
01296 "so"
01297 "es"
01298 "su"
01299 "sw"
01300 "sv"
01301 "tl"
01302 "tg"
01303 "ta"
01304 "tt"
01305 "te"
01306 "th"
01307 "bo"
01308 "ti"
01309 "to"
01310 "ts"
01311 "tr"
01312 "tk"
01313 "tw"
01314 "ug"
01315 "uk"
01316 "ur"
01317 "uz"
01318 "vi"
01319 "vo"
01320 "cy"
01321 "wo"
01322 "xh"
01323 "yi"
01324 "yo"
01325 "za"
01326 "zu"
01327 ;
01328
01329 static const char country_code_list[] =
01330 " "
01331 "AF"
01332 "AL"
01333 "DZ"
01334 "AS"
01335 "AD"
01336 "AO"
01337 "AI"
01338 "AQ"
01339 "AG"
01340 "AR"
01341 "AM"
01342 "AW"
01343 "AU"
01344 "AT"
01345 "AZ"
01346 "BS"
01347 "BH"
01348 "BD"
01349 "BB"
01350 "BY"
01351 "BE"
01352 "BZ"
01353 "BJ"
01354 "BM"
01355 "BT"
01356 "BO"
01357 "BA"
01358 "BW"
01359 "BV"
01360 "BR"
01361 "IO"
01362 "BN"
01363 "BG"
01364 "BF"
01365 "BI"
01366 "KH"
01367 "CM"
01368 "CA"
01369 "CV"
01370 "KY"
01371 "CF"
01372 "TD"
01373 "CL"
01374 "CN"
01375 "CX"
01376 "CC"
01377 "CO"
01378 "KM"
01379 "CD"
01380 "CG"
01381 "CK"
01382 "CR"
01383 "CI"
01384 "HR"
01385 "CU"
01386 "CY"
01387 "CZ"
01388 "DK"
01389 "DJ"
01390 "DM"
01391 "DO"
01392 "TL"
01393 "EC"
01394 "EG"
01395 "SV"
01396 "GQ"
01397 "ER"
01398 "EE"
01399 "ET"
01400 "FK"
01401 "FO"
01402 "FJ"
01403 "FI"
01404 "FR"
01405 "FX"
01406 "GF"
01407 "PF"
01408 "TF"
01409 "GA"
01410 "GM"
01411 "GE"
01412 "DE"
01413 "GH"
01414 "GI"
01415 "GR"
01416 "GL"
01417 "GD"
01418 "GP"
01419 "GU"
01420 "GT"
01421 "GN"
01422 "GW"
01423 "GY"
01424 "HT"
01425 "HM"
01426 "HN"
01427 "HK"
01428 "HU"
01429 "IS"
01430 "IN"
01431 "ID"
01432 "IR"
01433 "IQ"
01434 "IE"
01435 "IL"
01436 "IT"
01437 "JM"
01438 "JP"
01439 "JO"
01440 "KZ"
01441 "KE"
01442 "KI"
01443 "KP"
01444 "KR"
01445 "KW"
01446 "KG"
01447 "LA"
01448 "LV"
01449 "LB"
01450 "LS"
01451 "LR"
01452 "LY"
01453 "LI"
01454 "LT"
01455 "LU"
01456 "MO"
01457 "MK"
01458 "MG"
01459 "MW"
01460 "MY"
01461 "MV"
01462 "ML"
01463 "MT"
01464 "MH"
01465 "MQ"
01466 "MR"
01467 "MU"
01468 "YT"
01469 "MX"
01470 "FM"
01471 "MD"
01472 "MC"
01473 "MN"
01474 "MS"
01475 "MA"
01476 "MZ"
01477 "MM"
01478 "NA"
01479 "NR"
01480 "NP"
01481 "NL"
01482 "AN"
01483 "NC"
01484 "NZ"
01485 "NI"
01486 "NE"
01487 "NG"
01488 "NU"
01489 "NF"
01490 "MP"
01491 "NO"
01492 "OM"
01493 "PK"
01494 "PW"
01495 "PS"
01496 "PA"
01497 "PG"
01498 "PY"
01499 "PE"
01500 "PH"
01501 "PN"
01502 "PL"
01503 "PT"
01504 "PR"
01505 "QA"
01506 "RE"
01507 "RO"
01508 "RU"
01509 "RW"
01510 "KN"
01511 "LC"
01512 "VC"
01513 "WS"
01514 "SM"
01515 "ST"
01516 "SA"
01517 "SN"
01518 "SC"
01519 "SL"
01520 "SG"
01521 "SK"
01522 "SI"
01523 "SB"
01524 "SO"
01525 "ZA"
01526 "GS"
01527 "ES"
01528 "LK"
01529 "SH"
01530 "PM"
01531 "SD"
01532 "SR"
01533 "SJ"
01534 "SZ"
01535 "SE"
01536 "CH"
01537 "SY"
01538 "TW"
01539 "TJ"
01540 "TZ"
01541 "TH"
01542 "TG"
01543 "TK"
01544 "TO"
01545 "TT"
01546 "TN"
01547 "TR"
01548 "TM"
01549 "TC"
01550 "TV"
01551 "UG"
01552 "UA"
01553 "AE"
01554 "GB"
01555 "US"
01556 "UM"
01557 "UY"
01558 "UZ"
01559 "VU"
01560 "VA"
01561 "VE"
01562 "VN"
01563 "VG"
01564 "VI"
01565 "WF"
01566 "EH"
01567 "YE"
01568 "YU"
01569 "ZM"
01570 "ZW"
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)
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
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
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];
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 {
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 {
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;
02980 QString num_str;
02981
02982
02983 double tmp_infinity = INFINITY;
02984
02985
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
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
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
03043
03044
03045
03046
03047
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
03096
03097 if (flags & QLocalePrivate::ZeroPadded
03098 && !(flags & QLocalePrivate::LeftAdjusted)
03099 && !special_number) {
03100 int num_pad_chars = width - (int)num_str.length();
03101
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
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
03138 flags &= ~AlwaysShowSign;
03139 flags &= ~BlankBeforePositive;
03140 negative = false;
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(); 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
03167
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
03176 if (negative
03177 || flags & AlwaysShowSign
03178 || flags & BlankBeforePositive)
03179 --num_pad_chars;
03180
03181
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
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(); 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
03240
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
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
03281 bool QLocalePrivate::removeGroupSeparators(QString &num_str) const
03282 {
03283 int group_cnt = 0;
03284 int decpt_idx = -1;
03285
03286
03287 uint i = 0;
03288 for (; i < num_str.length(); ++i) {
03289 QChar c = num_str.unicode()[i];
03290
03291 if (c == group()) {
03292
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
03301 if (decpt_idx != -1)
03302 return false;
03303 decpt_idx = i;
03304 } else if (c == exponential() || c == exponential().upper()) {
03305
03306
03307 if (decpt_idx == -1)
03308 decpt_idx = i;
03309 }
03310 }
03311
03312
03313 if (group_cnt == 0)
03314 return true;
03315
03316
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
03326 if ((int)i > decpt_idx)
03327 return false;
03328
03329
03330 if ((decpt_idx - i) % 4 != 0)
03331 return false;
03332
03333
03334 num_str.remove(i, 1);
03335
03336 --group_cnt;
03337 --decpt_idx;
03338 } else {
03339
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
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')
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 ;
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
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
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
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
03656
03657
03658
03659
03660
03661
03662
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
03677
03678
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
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
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
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
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
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846 #define IEEE_BIG_OR_LITTLE_ENDIAN 1
03847
03848 #ifdef __arm32__
03849
03850
03851
03852
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)
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
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
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
03932
03933
03934
03935
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)
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
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
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
04040
04041
04042
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
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
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;
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;
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
04789
04790
04791
04792
04793
04794
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;
04808
04809
04810
04811
04812
04813
04814
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
04909
04910
04911 e = 19999;
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
04931
04932
04933
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 rounded_product(rv, tens[e]);
04955 goto ret;
04956 #endif
04957 }
04958 i = DBL_DIG - nd;
04959 if (e <= Ten_pmax + i) {
04960
04961
04962
04963 e -= i;
04964 rv *= tens[i];
04965 #ifdef VAX
04966
04967
04968
04969 vax_ovfl_check:
04970 word0(rv) -= P*Exp_msk1;
04971 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 rounded_product(rv, tens[e]);
04978 #endif
04979 goto ret;
04980 }
04981 }
04982 #ifndef Inaccurate_Divide
04983 else if (e >= -Ten_pmax) {
04984 rounded_quotient(rv, tens[-e]);
04985 goto ret;
04986 }
04987 #endif
04988 }
04989 e1 += nd - k;
04990
04991
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
05000 if (ok != 0)
05001 *ok = false;
05002 #ifdef __STDC__
05003 rv = HUGE_VAL;
05004 #else
05005
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
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
05030
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
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
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
05072
05073
05074 }
05075 }
05076 }
05077
05078
05079
05080
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);
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;
05111 if (i < Emin)
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
05146
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
05157 if (dsign) {
05158 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
05159 && word1(rv) == 0xffffffff) {
05160
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
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
05224
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:
05239 aadj1 -= 0.5;
05240 break;
05241 case 0:
05242 case 3:
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
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
05299
05300
05301
05302
05303
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
05317 L = (Long) aadj;
05318 aadj -= L;
05319
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 if (b->wds > n)
05359 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);
05368 #ifdef BSD_QDTOA_DEBUG
05369 if (q > 9)
05370 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
05446
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476
05477
05478
05479
05480
05481
05482
05483 static char *qdtoa (volatile double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
05484 {
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514
05515
05516
05517
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;
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;
05531 volatile double d2;
05532 double ds, eps;
05533 char *s, *s0;
05534
05535 if (word0(d) & Sign_bit) {
05536
05537 *sign = 1;
05538 word0(d) &= ~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
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;
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
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607
05608
05609
05610
05611
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
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;
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--;
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
05681 case 4:
05682 if (ndigits <= 0)
05683 ndigits = 1;
05684 ilim = ilim1 = i = ndigits;
05685 break;
05686 case 3:
05687 leftright = 0;
05688
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
05702
05703 i = 0;
05704 d2 = d;
05705 k0 = k;
05706 ilim0 = ilim;
05707 ieps = 2;
05708 if (k > 0) {
05709 ds = tens[k&0xf];
05710 j = k >> 4;
05711 if (j & Bletch) {
05712
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
05754
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
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
05801
05802 if (be >= 0 && k <= Int_max) {
05803
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
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
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
05908 b2 += Log2P;
05909 s2 += Log2P;
05910 spec_case = 1;
05911 }
05912 else
05913 spec_case = 0;
05914 }
05915
05916
05917
05918
05919
05920
05921
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);
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
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
05972
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
05985
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') {
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
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) {
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