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
#include <clocale>
00030
#include <cstring>
00031
#include <cassert>
00032
#include <cctype>
00033
#include <cwctype>
00034
#include <locale>
00035
#include <bits/atomicity.h>
00036
00037
namespace __gnu_cxx
00038 {
00039
00040
extern std::locale c_locale;
00041
extern std::locale::_Impl c_locale_impl;
00042 }
00043
00044
namespace std
00045 {
00046
using namespace __gnu_cxx;
00047
00048
00049
const locale::category locale::none;
00050
const locale::category locale::ctype;
00051
const locale::category locale::numeric;
00052
const locale::category locale::collate;
00053
const locale::category locale::time;
00054
const locale::category locale::monetary;
00055
const locale::category locale::messages;
00056
const locale::category locale::all;
00057
00058
00059
00060
00061 locale::_Impl* locale::_S_classic;
00062 locale::_Impl* locale::_S_global;
00063
const size_t locale::_S_categories_size;
00064 _GLIBCPP_ASM_SYMVER(_ZNSt6locale18_S_categories_sizeE, _ZNSt6locale17_S_num_categoriesE, GLIBCPP_3.2)
00065
const size_t locale::_S_extra_categories_size;
00066
00067
00068 _Atomic_word locale::id::_S_highwater;
00069
00070
00071
const locale::id*
const
00072 locale::_Impl::_S_id_ctype[] =
00073 {
00074 &std::ctype<char>::
id,
00075 &codecvt<char, char, mbstate_t>::
id,
00076 #ifdef _GLIBCPP_USE_WCHAR_T
00077 &std::ctype<wchar_t>::
id,
00078 &codecvt<wchar_t, char, mbstate_t>::
id,
00079 #endif
00080 0
00081 };
00082
00083
const locale::id*
const
00084 locale::_Impl::_S_id_numeric[] =
00085 {
00086 &num_get<char>::id,
00087 &num_put<char>::id,
00088 &numpunct<char>::id,
00089
#ifdef _GLIBCPP_USE_WCHAR_T
00090
&num_get<wchar_t>::id,
00091 &num_put<wchar_t>::id,
00092 &numpunct<wchar_t>::id,
00093
#endif
00094
0
00095 };
00096
00097
const locale::id*
const
00098 locale::_Impl::_S_id_collate[] =
00099 {
00100 &std::collate<char>::id,
00101
#ifdef _GLIBCPP_USE_WCHAR_T
00102
&std::collate<wchar_t>::id,
00103
#endif
00104
0
00105 };
00106
00107
const locale::id*
const
00108 locale::_Impl::_S_id_time[] =
00109 {
00110 &__timepunct<char>::id,
00111 &time_get<char>::id,
00112 &time_put<char>::id,
00113
#ifdef _GLIBCPP_USE_WCHAR_T
00114
&__timepunct<wchar_t>::id,
00115 &time_get<wchar_t>::id,
00116 &time_put<wchar_t>::id,
00117
#endif
00118
0
00119 };
00120
00121
const locale::id*
const
00122 locale::_Impl::_S_id_monetary[] =
00123 {
00124 &money_get<char>::id,
00125 &money_put<char>::id,
00126 &moneypunct<char, false>::id,
00127 &moneypunct<char, true >::id,
00128
#ifdef _GLIBCPP_USE_WCHAR_T
00129
&money_get<wchar_t>::id,
00130 &money_put<wchar_t>::id,
00131 &moneypunct<wchar_t, false>::id,
00132 &moneypunct<wchar_t, true >::id,
00133
#endif
00134
0
00135 };
00136
00137
const locale::id*
const
00138 locale::_Impl::_S_id_messages[] =
00139 {
00140 &std::messages<char>::id,
00141
#ifdef _GLIBCPP_USE_WCHAR_T
00142
&std::messages<wchar_t>::id,
00143
#endif
00144
0
00145 };
00146
00147
const locale::id*
const*
const
00148 locale::_Impl::_S_facet_categories[] =
00149 {
00150
00151 locale::_Impl::_S_id_ctype,
00152 locale::_Impl::_S_id_numeric,
00153 locale::_Impl::_S_id_collate,
00154 locale::_Impl::_S_id_time,
00155 locale::_Impl::_S_id_monetary,
00156 locale::_Impl::_S_id_messages,
00157 0
00158 };
00159
00160 locale::locale() throw()
00161 {
00162 _S_initialize();
00163 (_M_impl = _S_global)->_M_add_reference();
00164 }
00165
00166 locale::locale(
const locale& __other)
throw()
00167 { (_M_impl = __other._M_impl)->_M_add_reference(); }
00168
00169
00170
00171
00172 locale::locale(_Impl* __ip)
throw() : _M_impl(__ip)
00173 { }
00174
00175 locale::locale(
const char* __s)
00176 {
00177
if (__s)
00178 {
00179 _S_initialize();
00180
if (strcmp(__s,
"C") == 0 || strcmp(__s,
"POSIX") == 0)
00181 (_M_impl = _S_classic)->_M_add_reference();
00182
else if (strcmp(__s,
"") != 0)
00183 _M_impl =
new _Impl(__s, 1);
00184
else
00185 {
00186
00187
char* __env = getenv(
"LC_ALL");
00188
00189
if (__env && strcmp(__env,
"") != 0)
00190 {
00191
if (strcmp(__env,
"C") == 0 || strcmp(__env,
"POSIX") == 0)
00192 (_M_impl = _S_classic)->_M_add_reference();
00193
else
00194 _M_impl =
new _Impl(__env, 1);
00195 }
00196
else
00197 {
00198
char* __res;
00199
00200
char* __env = getenv(
"LANG");
00201
if (!__env || strcmp(__env,
"") == 0 || strcmp(__env,
"C") == 0
00202 || strcmp(__env,
"POSIX") == 0)
00203 __res = strdup(
"C");
00204
else
00205 __res = strdup(__env);
00206
00207
00208
00209 size_t __i = 0;
00210
if (strcmp(__res,
"C") == 0)
00211
for (__i = 0;
00212 __i < _S_categories_size + _S_extra_categories_size;
00213 ++__i)
00214 {
00215 __env = getenv(_S_categories[__i]);
00216
if (__env && strcmp(__env,
"") != 0
00217 && strcmp(__env,
"C") != 0
00218 && strcmp(__env,
"POSIX") != 0)
00219
break;
00220 }
00221
else
00222
for (__i = 0;
00223 __i < _S_categories_size + _S_extra_categories_size;
00224 ++__i)
00225 {
00226 __env = getenv(_S_categories[__i]);
00227
if (__env && strcmp(__env,
"") != 0
00228 && strcmp(__env, __res) != 0)
00229
break;
00230 }
00231
00232
00233
00234
if (__i < _S_categories_size + _S_extra_categories_size)
00235 {
00236 string __str;
00237
for (size_t __j = 0; __j < __i; ++__j)
00238 {
00239 __str += _S_categories[__j];
00240 __str +=
"=";
00241 __str += __res;
00242 __str +=
";";
00243 }
00244 __str += _S_categories[__i];
00245 __str +=
"=";
00246 __str += __env;
00247 __str +=
";";
00248 __i++;
00249
for (; __i < _S_categories_size
00250 + _S_extra_categories_size; ++__i)
00251 {
00252 __env = getenv(_S_categories[__i]);
00253
if (!__env || strcmp(__env,
"") == 0)
00254 {
00255 __str += _S_categories[__i];
00256 __str +=
'=';
00257 __str += __res;
00258 __str +=
';';
00259 }
00260
else if (strcmp(__env,
"C") == 0
00261 || strcmp(__env,
"POSIX") == 0)
00262 {
00263 __str += _S_categories[__i];
00264 __str +=
"=C;";
00265 }
00266
else
00267 {
00268 __str += _S_categories[__i];
00269 __str +=
"=";
00270 __str += __env;
00271 __str +=
";";
00272 }
00273 }
00274 __str.erase(__str.end() - 1);
00275 _M_impl =
new _Impl(__str.c_str(), 1);
00276 }
00277
00278
00279
else if (strcmp(__res,
"C") == 0)
00280 (_M_impl = _S_classic)->_M_add_reference();
00281
else
00282 _M_impl =
new _Impl(__res, 1);
00283 free(__res);
00284 }
00285 }
00286 }
00287
else
00288 __throw_runtime_error(
"attempt to create locale from NULL name");
00289 }
00290
00291 locale::locale(
const locale& __base,
const char* __s, category __cat)
00292 {
00293
00294
00295
00296 locale __add(__s);
00297 _M_coalesce(__base, __add, __cat);
00298 }
00299
00300 locale::locale(
const locale& __base,
const locale& __add, category __cat)
00301 { _M_coalesce(__base, __add, __cat); }
00302
00303 locale::~locale() throw()
00304 { _M_impl->_M_remove_reference(); }
00305
00306
bool
00307 locale::operator==(
const locale& __rhs)
const throw()
00308 {
00309 string __name = this->name();
00310
return (_M_impl == __rhs._M_impl
00311 || (__name !=
"*" && __name == __rhs.name()));
00312 }
00313
00314
const locale&
00315 locale::operator=(
const locale& __other)
throw()
00316 {
00317 __other._M_impl->_M_add_reference();
00318 _M_impl->_M_remove_reference();
00319 _M_impl = __other._M_impl;
00320
return *
this;
00321 }
00322
00323 locale
00324 locale::global(
const locale& __other)
00325 {
00326
00327 _S_initialize();
00328 _Impl* __old = _S_global;
00329 __other._M_impl->_M_add_reference();
00330 _S_global = __other._M_impl;
00331
if (_S_global->_M_check_same_name()
00332 && (strcmp(_S_global->_M_names[0],
"*") != 0))
00333 setlocale(LC_ALL, __other.name().c_str());
00334
00335
00336
00337
00338
00339
00340
return locale(__old);
00341 }
00342
00343 string
00344 locale::name()
const
00345
{
00346 string __ret;
00347
if (_M_impl->_M_check_same_name())
00348 __ret = _M_impl->_M_names[0];
00349
else
00350 {
00351 __ret += _S_categories[0];
00352 __ret +=
"=";
00353 __ret += _M_impl->_M_names[0];
00354
for (size_t __i = 1;
00355 __i < _S_categories_size + _S_extra_categories_size;
00356 ++__i)
00357 {
00358 __ret +=
";";
00359 __ret += _S_categories[__i];
00360 __ret +=
"=";
00361 __ret += _M_impl->_M_names[__i];
00362 }
00363 }
00364
return __ret;
00365 }
00366
00367
const locale&
00368 locale::classic()
00369 {
00370
00371
if (!_S_classic)
00372 {
00373
try
00374 {
00375
00376
00377 _S_classic =
new (&c_locale_impl) _Impl(0, 2,
true);
00378 _S_global = _S_classic;
00379
new (&c_locale) locale(_S_classic);
00380 }
00381
catch(...)
00382 {
00383
00384
00385
if (_S_classic)
00386 _S_classic->~_Impl();
00387 _S_classic = _S_global = 0;
00388 __throw_exception_again;
00389 }
00390 }
00391
return c_locale;
00392 }
00393
00394
void
00395 locale::_M_coalesce(
const locale& __base,
const locale& __add,
00396 category __cat)
00397 {
00398 __cat = _S_normalize_category(__cat);
00399 _M_impl =
new _Impl(*__base._M_impl, 1);
00400
00401
try
00402 { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
00403
catch (...)
00404 {
00405 _M_impl->_M_remove_reference();
00406 __throw_exception_again;
00407 }
00408 }
00409
00410 locale::category
00411 locale::_S_normalize_category(category __cat)
00412 {
00413
int __ret = 0;
00414
if (__cat == none || (__cat & all) && !(__cat & ~all))
00415 __ret = __cat;
00416
else
00417 {
00418
00419
switch (__cat)
00420 {
00421
case LC_COLLATE:
00422 __ret = collate;
00423
break;
00424
case LC_CTYPE:
00425 __ret = ctype;
00426
break;
00427
case LC_MONETARY:
00428 __ret = monetary;
00429
break;
00430
case LC_NUMERIC:
00431 __ret = numeric;
00432
break;
00433
case LC_TIME:
00434 __ret = time;
00435
break;
00436
#ifdef _GLIBCPP_HAVE_LC_MESSAGES
00437
case LC_MESSAGES:
00438 __ret = messages;
00439
break;
00440
#endif
00441
case LC_ALL:
00442 __ret = all;
00443
break;
00444
default:
00445 __throw_runtime_error(
"bad locale category");
00446 }
00447 }
00448
return __ret;
00449 }
00450
00451 __c_locale
00452 locale::facet::_S_c_locale;
00453
00454
char locale::facet::_S_c_name[2];
00455
00456 locale::facet::
00457 ~facet() { }
00458
00459 locale::facet::
00460 facet(size_t __refs)
throw() : _M_references(__refs ? 1 : 0)
00461 { }
00462
00463
void
00464 locale::facet::
00465 _M_add_reference() throw()
00466 { __atomic_add(&_M_references, 1); }
00467
00468
void
00469 locale::facet::
00470 _M_remove_reference() throw()
00471 {
00472
if (__exchange_and_add(&_M_references, -1) == 1)
00473 {
00474
try
00475 {
delete this; }
00476
catch (...)
00477 { }
00478 }
00479 }
00480
00481 locale::id::id()
00482 { }
00483
00484
00485
template<>
00486
const char*
00487 __timepunct<char>::_S_timezones[14] =
00488 {
00489
"GMT",
"HST",
"AKST",
"PST",
"MST",
"CST",
"EST",
"AST",
"NST",
"CET",
00490
"IST",
"EET",
"CST",
"JST"
00491 };
00492
00493
#ifdef _GLIBCPP_USE_WCHAR_T
00494
template<>
00495
const wchar_t*
00496 __timepunct<wchar_t>::_S_timezones[14] =
00497 {
00498 L
"GMT", L
"HST", L
"AKST", L
"PST", L
"MST", L
"CST", L
"EST", L
"AST",
00499 L
"NST", L
"CET", L
"IST", L
"EET", L
"CST", L
"JST"
00500 };
00501
#endif
00502
00503
00504
const money_base::pattern
00505 money_base::_S_default_pattern = { {symbol, sign, none, value} };
00506
00507
const char __num_base::_S_atoms[] =
"0123456789eEabcdfABCDF";
00508
00509
bool
00510 __num_base::_S_format_float(
const ios_base& __io,
char* __fptr,
char __mod,
00511 streamsize __prec)
00512 {
00513
bool __incl_prec =
false;
00514 ios_base::fmtflags __flags = __io.flags();
00515 *__fptr++ =
'%';
00516
00517
if (__flags & ios_base::showpos)
00518 *__fptr++ =
'+';
00519
if (__flags & ios_base::showpoint)
00520 *__fptr++ =
'#';
00521
00522
if (__flags & ios_base::fixed || __prec > 0)
00523 {
00524 *__fptr++ =
'.';
00525 *__fptr++ =
'*';
00526 __incl_prec =
true;
00527 }
00528
if (__mod)
00529 *__fptr++ = __mod;
00530 ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
00531
00532
if (__fltfield == ios_base::fixed)
00533 *__fptr++ =
'f';
00534
else if (__fltfield == ios_base::scientific)
00535 *__fptr++ = (__flags & ios_base::uppercase) ?
'E' :
'e';
00536
else
00537 *__fptr++ = (__flags & ios_base::uppercase) ?
'G' :
'g';
00538 *__fptr =
'\0';
00539
return __incl_prec;
00540 }
00541
00542
void
00543 __num_base::_S_format_int(
const ios_base& __io,
char* __fptr,
char __mod,
00544
char __modl)
00545 {
00546 ios_base::fmtflags __flags = __io.flags();
00547 *__fptr++ =
'%';
00548
00549
if (__flags & ios_base::showpos)
00550 *__fptr++ =
'+';
00551
if (__flags & ios_base::showbase)
00552 *__fptr++ =
'#';
00553 *__fptr++ =
'l';
00554
00555
00556
if (__modl)
00557 *__fptr++ = __modl;
00558
00559 ios_base::fmtflags __bsefield = __flags & ios_base::basefield;
00560
if (__bsefield == ios_base::hex)
00561 *__fptr++ = (__flags & ios_base::uppercase) ?
'X' :
'x';
00562
else if (__bsefield == ios_base::oct)
00563 *__fptr++ =
'o';
00564
else
00565 *__fptr++ = __mod;
00566 *__fptr =
'\0';
00567 }
00568 }
00569