1 /* 2 * Copyright (c) 1999 3 * Silicon Graphics Computer Systems, Inc. 4 * 5 * Copyright (c) 1999 6 * Boris Fomitchev 7 * 8 * This material is provided "as is", with absolutely no warranty expressed 9 * or implied. Any use is at your own risk. 10 * 11 * Permission to use or copy this software for any purpose is hereby granted 12 * without fee, provided the above notices are retained on all copies. 13 * Permission to modify the code and to distribute modified code is granted, 14 * provided the above notices are retained, and a notice that the code was 15 * modified is included with the above copyright notice. 16 * 17 */ 18 #include "stlport_prefix.h" 19 20 #include <locale> 21 #include <algorithm> 22 #include <typeinfo> 23 24 #include "c_locale.h" 25 #include "aligned_buffer.h" 26 #include "acquire_release.h" 27 #include "locale_impl.h" 28 29 _STLP_BEGIN_NAMESPACE 30 31 static const string _Nameless("*"); 32 33 static inline bool is_C_locale_name (const char* name) 34 { return ((name[0] == 'C') && (name[1] == 0)); } 35 36 locale::facet * _STLP_CALL _get_facet(locale::facet *f) 37 { 38 if (f != 0) 39 f->_M_incr(); 40 return f; 41 } 42 43 void _STLP_CALL _release_facet(locale::facet *&f) 44 { 45 if ((f != 0) && (f->_M_decr() == 0)) { 46 delete f; 47 f = 0; 48 } 49 } 50 51 size_t locale::id::_S_max = 27; 52 53 static void _Stl_loc_assign_ids(); 54 55 static _Stl_aligned_buffer<_Locale_impl::Init> __Loc_init_buf; 56 57 _Locale_impl::Init::Init() { 58 if (_M_count()._M_incr() == 1) { 59 _Locale_impl::_S_initialize(); 60 } 61 } 62 63 _Locale_impl::Init::~Init() { 64 if (_M_count()._M_decr() == 0) { 65 _Locale_impl::_S_uninitialize(); 66 } 67 } 68 69 _Refcount_Base& _Locale_impl::Init::_M_count() const { 70 static _Refcount_Base _S_count(0); 71 return _S_count; 72 } 73 74 _Locale_impl::_Locale_impl(const char* s) 75 : _Refcount_Base(0), name(s), facets_vec() { 76 facets_vec.reserve( locale::id::_S_max ); 77 new (&__Loc_init_buf) Init(); 78 } 79 80 _Locale_impl::_Locale_impl( _Locale_impl const& locimpl ) 81 : _Refcount_Base(0), name(locimpl.name), facets_vec() { 82 for_each( locimpl.facets_vec.begin(), locimpl.facets_vec.end(), _get_facet); 83 facets_vec = locimpl.facets_vec; 84 new (&__Loc_init_buf) Init(); 85 } 86 87 _Locale_impl::_Locale_impl( size_t n, const char* s) 88 : _Refcount_Base(0), name(s), facets_vec(n, 0) { 89 new (&__Loc_init_buf) Init(); 90 } 91 92 _Locale_impl::~_Locale_impl() { 93 (&__Loc_init_buf)->~Init(); 94 for_each( facets_vec.begin(), facets_vec.end(), _release_facet); 95 } 96 97 // Initialization of the locale system. This must be called before 98 // any locales are constructed. (Meaning that it must be called when 99 // the I/O library itself is initialized.) 100 void _STLP_CALL _Locale_impl::_S_initialize() { 101 _Stl_loc_assign_ids(); 102 make_classic_locale(); 103 } 104 105 // Release of the classic locale ressources. Has to be called after the last 106 // locale destruction and not only after the classic locale destruction as 107 // the facets can be shared between different facets. 108 void _STLP_CALL _Locale_impl::_S_uninitialize() { 109 //Not necessary anymore as classic facets are now 'normal' dynamically allocated 110 //facets with a reference counter telling to _release_facet when the facet can be 111 //deleted. 112 //free_classic_locale(); 113 } 114 115 // _Locale_impl non-inline member functions. 116 void _STLP_CALL _Locale_impl::_M_throw_bad_cast() { 117 _STLP_THROW(bad_cast()); 118 } 119 120 void _Locale_impl::insert(_Locale_impl *from, const locale::id& n) { 121 if (n._M_index > 0 && n._M_index < from->size()) { 122 this->insert(from->facets_vec[n._M_index], n); 123 } 124 } 125 126 locale::facet* _Locale_impl::insert(locale::facet *f, const locale::id& n) { 127 if (f == 0 || n._M_index == 0) 128 return 0; 129 130 if (n._M_index >= facets_vec.size()) { 131 facets_vec.resize(n._M_index + 1); 132 } 133 134 if (f != facets_vec[n._M_index]) 135 { 136 _release_facet(facets_vec[n._M_index]); 137 facets_vec[n._M_index] = _get_facet(f); 138 } 139 140 return f; 141 } 142 143 // 144 // <locale> content which is dependent on the name 145 // 146 147 /* Six functions, one for each category. Each of them takes a 148 * a name, constructs that appropriate category facets by name, 149 * and inserts them into the locale. */ 150 _Locale_name_hint* _Locale_impl::insert_ctype_facets(const char* &name, char *buf, _Locale_name_hint* hint) { 151 if (name[0] == 0) 152 name = _Locale_ctype_default(buf); 153 154 if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { 155 _Locale_impl* i2 = locale::classic()._M_impl; 156 this->insert(i2, ctype<char>::id); 157 this->insert(i2, codecvt<char, char, mbstate_t>::id); 158 #ifndef _STLP_NO_WCHAR_T 159 this->insert(i2, ctype<wchar_t>::id); 160 this->insert(i2, codecvt<wchar_t, char, mbstate_t>::id); 161 #endif 162 } else { 163 locale::facet* ct = 0; 164 locale::facet* cvt = 0; 165 #ifndef _STLP_NO_WCHAR_T 166 locale::facet* wct = 0; 167 locale::facet* wcvt = 0; 168 #endif 169 int __err_code; 170 _Locale_ctype *__lct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code); 171 if (!__lct) { 172 locale::_M_throw_on_creation_failure(__err_code, name, "ctype"); 173 return hint; 174 } 175 176 if (hint == 0) hint = _Locale_get_ctype_hint(__lct); 177 178 _STLP_TRY { 179 ct = new ctype_byname<char>(__lct); 180 } 181 _STLP_UNWIND(_STLP_PRIV __release_ctype(__lct)); 182 183 _STLP_TRY { 184 cvt = new codecvt_byname<char, char, mbstate_t>(name); 185 } 186 _STLP_UNWIND(delete ct); 187 188 #ifndef _STLP_NO_WCHAR_T 189 _STLP_TRY { 190 _Locale_ctype *__lwct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code); 191 if (!__lwct) { 192 locale::_M_throw_on_creation_failure(__err_code, name, "ctype"); 193 return hint; 194 } 195 196 _STLP_TRY { 197 wct = new ctype_byname<wchar_t>(__lwct); 198 } 199 _STLP_UNWIND(_STLP_PRIV __release_ctype(__lwct)); 200 201 _Locale_codecvt *__lwcvt = _STLP_PRIV __acquire_codecvt(name, buf, hint, &__err_code); 202 if (__lwcvt) { 203 _STLP_TRY { 204 wcvt = new codecvt_byname<wchar_t, char, mbstate_t>(__lwcvt); 205 } 206 _STLP_UNWIND(_STLP_PRIV __release_codecvt(__lwcvt); delete wct); 207 } 208 } 209 _STLP_UNWIND(delete cvt; delete ct); 210 #endif 211 212 this->insert(ct, ctype<char>::id); 213 this->insert(cvt, codecvt<char, char, mbstate_t>::id); 214 #ifndef _STLP_NO_WCHAR_T 215 this->insert(wct, ctype<wchar_t>::id); 216 if (wcvt) this->insert(wcvt, codecvt<wchar_t, char, mbstate_t>::id); 217 #endif 218 } 219 return hint; 220 } 221 222 _Locale_name_hint* _Locale_impl::insert_numeric_facets(const char* &name, char *buf, _Locale_name_hint* hint) { 223 if (name[0] == 0) 224 name = _Locale_numeric_default(buf); 225 226 _Locale_impl* i2 = locale::classic()._M_impl; 227 228 // We first insert name independant facets taken from the classic locale instance: 229 this->insert(i2, 230 num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 231 this->insert(i2, 232 num_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 233 #ifndef _STLP_NO_WCHAR_T 234 this->insert(i2, 235 num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 236 this->insert(i2, 237 num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 238 #endif 239 240 if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { 241 this->insert(i2, numpunct<char>::id); 242 #ifndef _STLP_NO_WCHAR_T 243 this->insert(i2, numpunct<wchar_t>::id); 244 #endif 245 } 246 else { 247 locale::facet* punct = 0; 248 #ifndef _STLP_NO_WCHAR_T 249 locale::facet* wpunct = 0; 250 #endif 251 252 int __err_code; 253 _Locale_numeric *__lpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code); 254 if (!__lpunct) { 255 locale::_M_throw_on_creation_failure(__err_code, name, "numpunct"); 256 return hint; 257 } 258 259 if (hint == 0) hint = _Locale_get_numeric_hint(__lpunct); 260 _STLP_TRY { 261 punct = new numpunct_byname<char>(__lpunct); 262 } 263 _STLP_UNWIND(_STLP_PRIV __release_numeric(__lpunct)); 264 265 #ifndef _STLP_NO_WCHAR_T 266 _Locale_numeric *__lwpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code); 267 if (!__lwpunct) { 268 delete punct; 269 locale::_M_throw_on_creation_failure(__err_code, name, "numpunct"); 270 return hint; 271 } 272 if (__lwpunct) { 273 _STLP_TRY { 274 wpunct = new numpunct_byname<wchar_t>(__lwpunct); 275 } 276 _STLP_UNWIND(_STLP_PRIV __release_numeric(__lwpunct); delete punct); 277 } 278 #endif 279 280 this->insert(punct, numpunct<char>::id); 281 #ifndef _STLP_NO_WCHAR_T 282 this->insert(wpunct, numpunct<wchar_t>::id); 283 #endif 284 } 285 return hint; 286 } 287 288 _Locale_name_hint* _Locale_impl::insert_time_facets(const char* &name, char *buf, _Locale_name_hint* hint) { 289 if (name[0] == 0) 290 name = _Locale_time_default(buf); 291 292 if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { 293 _Locale_impl* i2 = locale::classic()._M_impl; 294 this->insert(i2, 295 time_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 296 this->insert(i2, 297 time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 298 #ifndef _STLP_NO_WCHAR_T 299 this->insert(i2, 300 time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 301 this->insert(i2, 302 time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 303 #endif 304 } else { 305 locale::facet *get = 0; 306 locale::facet *put = 0; 307 #ifndef _STLP_NO_WCHAR_T 308 locale::facet *wget = 0; 309 locale::facet *wput = 0; 310 #endif 311 312 int __err_code; 313 _Locale_time *__time = _STLP_PRIV __acquire_time(name, buf, hint, &__err_code); 314 if (!__time) { 315 // time facets category is not mandatory for correct stream behavior so if platform 316 // do not support it we do not generate a runtime_error exception. 317 if (__err_code == _STLP_LOC_NO_MEMORY) { 318 _STLP_THROW_BAD_ALLOC; 319 } 320 return hint; 321 } 322 323 if (!hint) hint = _Locale_get_time_hint(__time); 324 _STLP_TRY { 325 get = new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(__time); 326 put = new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(__time); 327 #ifndef _STLP_NO_WCHAR_T 328 wget = new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(__time); 329 wput = new time_put_byname<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(__time); 330 #endif 331 } 332 #ifndef _STLP_NO_WCHAR_T 333 _STLP_UNWIND(delete wget; delete put; delete get; _STLP_PRIV __release_time(__time)); 334 #else 335 _STLP_UNWIND(delete get; _STLP_PRIV __release_time(__time)); 336 #endif 337 338 _STLP_PRIV __release_time(__time); 339 340 this->insert(get, time_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 341 this->insert(put, time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 342 #ifndef _STLP_NO_WCHAR_T 343 this->insert(wget, time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 344 this->insert(wput, time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 345 #endif 346 } 347 return hint; 348 } 349 350 _Locale_name_hint* _Locale_impl::insert_collate_facets(const char* &name, char *buf, _Locale_name_hint* hint) { 351 if (name[0] == 0) 352 name = _Locale_collate_default(buf); 353 354 if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { 355 _Locale_impl* i2 = locale::classic()._M_impl; 356 this->insert(i2, collate<char>::id); 357 #ifndef _STLP_NO_WCHAR_T 358 this->insert(i2, collate<wchar_t>::id); 359 #endif 360 } 361 else { 362 locale::facet *col = 0; 363 #ifndef _STLP_NO_WCHAR_T 364 locale::facet *wcol = 0; 365 #endif 366 367 int __err_code; 368 _Locale_collate *__coll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code); 369 if (!__coll) { 370 if (__err_code == _STLP_LOC_NO_MEMORY) { 371 _STLP_THROW_BAD_ALLOC; 372 } 373 return hint; 374 } 375 376 if (hint == 0) hint = _Locale_get_collate_hint(__coll); 377 _STLP_TRY { 378 col = new collate_byname<char>(__coll); 379 } 380 _STLP_UNWIND(_STLP_PRIV __release_collate(__coll)); 381 382 #ifndef _STLP_NO_WCHAR_T 383 _Locale_collate *__wcoll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code); 384 if (!__wcoll) { 385 if (__err_code == _STLP_LOC_NO_MEMORY) { 386 delete col; 387 _STLP_THROW_BAD_ALLOC; 388 } 389 } 390 if (__wcoll) { 391 _STLP_TRY { 392 wcol = new collate_byname<wchar_t>(__wcoll); 393 } 394 _STLP_UNWIND(_STLP_PRIV __release_collate(__wcoll); delete col); 395 } 396 #endif 397 398 this->insert(col, collate<char>::id); 399 #ifndef _STLP_NO_WCHAR_T 400 if (wcol) this->insert(wcol, collate<wchar_t>::id); 401 #endif 402 } 403 return hint; 404 } 405 406 _Locale_name_hint* _Locale_impl::insert_monetary_facets(const char* &name, char *buf, _Locale_name_hint* hint) { 407 if (name[0] == 0) 408 name = _Locale_monetary_default(buf); 409 410 _Locale_impl* i2 = locale::classic()._M_impl; 411 412 // We first insert name independant facets taken from the classic locale instance: 413 this->insert(i2, money_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 414 this->insert(i2, money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 415 #ifndef _STLP_NO_WCHAR_T 416 this->insert(i2, money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 417 this->insert(i2, money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 418 #endif 419 420 if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { 421 this->insert(i2, moneypunct<char, false>::id); 422 this->insert(i2, moneypunct<char, true>::id); 423 #ifndef _STLP_NO_WCHAR_T 424 this->insert(i2, moneypunct<wchar_t, false>::id); 425 this->insert(i2, moneypunct<wchar_t, true>::id); 426 #endif 427 } 428 else { 429 locale::facet *punct = 0; 430 locale::facet *ipunct = 0; 431 432 #ifndef _STLP_NO_WCHAR_T 433 locale::facet* wpunct = 0; 434 locale::facet* wipunct = 0; 435 #endif 436 437 int __err_code; 438 _Locale_monetary *__mon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); 439 if (!__mon) { 440 if (__err_code == _STLP_LOC_NO_MEMORY) { 441 _STLP_THROW_BAD_ALLOC; 442 } 443 return hint; 444 } 445 446 if (hint == 0) hint = _Locale_get_monetary_hint(__mon); 447 448 _STLP_TRY { 449 punct = new moneypunct_byname<char, false>(__mon); 450 } 451 _STLP_UNWIND(_STLP_PRIV __release_monetary(__mon)); 452 453 _Locale_monetary *__imon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); 454 if (!__imon) { 455 delete punct; 456 if (__err_code == _STLP_LOC_NO_MEMORY) { 457 _STLP_THROW_BAD_ALLOC; 458 } 459 return hint; 460 } 461 462 _STLP_TRY { 463 ipunct = new moneypunct_byname<char, true>(__imon); 464 } 465 _STLP_UNWIND(_STLP_PRIV __release_monetary(__imon); delete punct); 466 467 #ifndef _STLP_NO_WCHAR_T 468 _STLP_TRY { 469 _Locale_monetary *__wmon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); 470 if (!__wmon) { 471 if (__err_code == _STLP_LOC_NO_MEMORY) { 472 _STLP_THROW_BAD_ALLOC; 473 } 474 } 475 476 if (__wmon) { 477 _STLP_TRY { 478 wpunct = new moneypunct_byname<wchar_t, false>(__wmon); 479 } 480 _STLP_UNWIND(_STLP_PRIV __release_monetary(__wmon)); 481 482 _Locale_monetary *__wimon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code); 483 if (!__wimon) { 484 delete wpunct; 485 if (__err_code == _STLP_LOC_NO_MEMORY) { 486 _STLP_THROW_BAD_ALLOC; 487 } 488 wpunct = 0; 489 } 490 else { 491 _STLP_TRY { 492 wipunct = new moneypunct_byname<wchar_t, true>(__wimon); 493 } 494 _STLP_UNWIND(_STLP_PRIV __release_monetary(__wimon); delete wpunct); 495 } 496 } 497 } 498 _STLP_UNWIND(delete ipunct; delete punct); 499 #endif 500 501 this->insert(punct, moneypunct<char, false>::id); 502 this->insert(ipunct, moneypunct<char, true>::id); 503 #ifndef _STLP_NO_WCHAR_T 504 if (wpunct) this->insert(wpunct, moneypunct<wchar_t, false>::id); 505 if (wipunct) this->insert(wipunct, moneypunct<wchar_t, true>::id); 506 #endif 507 } 508 return hint; 509 } 510 511 _Locale_name_hint* _Locale_impl::insert_messages_facets(const char* &name, char *buf, _Locale_name_hint* hint) { 512 if (name[0] == 0) 513 name = _Locale_messages_default(buf); 514 515 if (name == 0 || name[0] == 0 || is_C_locale_name(name)) { 516 _Locale_impl* i2 = locale::classic()._M_impl; 517 this->insert(i2, messages<char>::id); 518 #ifndef _STLP_NO_WCHAR_T 519 this->insert(i2, messages<wchar_t>::id); 520 #endif 521 } 522 else { 523 locale::facet *msg = 0; 524 #ifndef _STLP_NO_WCHAR_T 525 locale::facet *wmsg = 0; 526 #endif 527 528 int __err_code; 529 _Locale_messages *__msg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code); 530 if (!__msg) { 531 if (__err_code == _STLP_LOC_NO_MEMORY) { 532 _STLP_THROW_BAD_ALLOC; 533 } 534 return hint; 535 } 536 537 _STLP_TRY { 538 msg = new messages_byname<char>(__msg); 539 } 540 _STLP_UNWIND(_STLP_PRIV __release_messages(__msg)); 541 542 #ifndef _STLP_NO_WCHAR_T 543 _STLP_TRY { 544 _Locale_messages *__wmsg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code); 545 if (!__wmsg) { 546 if (__err_code == _STLP_LOC_NO_MEMORY) { 547 _STLP_THROW_BAD_ALLOC; 548 } 549 } 550 551 if (__wmsg) { 552 _STLP_TRY { 553 wmsg = new messages_byname<wchar_t>(__wmsg); 554 } 555 _STLP_UNWIND(_STLP_PRIV __release_messages(__wmsg)); 556 } 557 } 558 _STLP_UNWIND(delete msg); 559 #endif 560 561 this->insert(msg, messages<char>::id); 562 #ifndef _STLP_NO_WCHAR_T 563 if (wmsg) this->insert(wmsg, messages<wchar_t>::id); 564 #endif 565 } 566 return hint; 567 } 568 569 static void _Stl_loc_assign_ids() { 570 // This assigns ids to every facet that is a member of a category, 571 // and also to money_get/put, num_get/put, and time_get/put 572 // instantiated using ordinary pointers as the input/output 573 // iterators. (The default is [io]streambuf_iterator.) 574 575 money_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index = 8; 576 money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index = 9; 577 num_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index = 10; 578 num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index = 11; 579 time_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index = 12; 580 time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index = 13; 581 582 #ifndef _STLP_NO_WCHAR_T 583 money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 21; 584 money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 22; 585 num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 23; 586 num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::id._M_index = 24; 587 time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 25; 588 time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 26; 589 #endif 590 // locale::id::_S_max = 27; 591 } 592 593 // To access those static instance use the getter below, they guaranty 594 // a correct initialization. 595 static locale *_Stl_classic_locale = 0; 596 static locale *_Stl_global_locale = 0; 597 598 locale* _Stl_get_classic_locale() { 599 static _Locale_impl::Init init; 600 return _Stl_classic_locale; 601 } 602 603 locale* _Stl_get_global_locale() { 604 static _Locale_impl::Init init; 605 return _Stl_global_locale; 606 } 607 608 #if defined (_STLP_MSVC) || defined (__ICL) || defined (__ISCPP__) || defined (__DMC__) 609 /* 610 * The following static variable needs to be initialized before STLport 611 * users static variable in order for him to be able to use Standard 612 * streams in its variable initialization. 613 * This variable is here because MSVC do not allow to change the initialization 614 * segment in a given translation unit, iostream.cpp already contains an 615 * initialization segment specification. 616 */ 617 # pragma warning (disable : 4073) 618 # pragma init_seg(lib) 619 #endif 620 621 static ios_base::Init _IosInit; 622 623 void _Locale_impl::make_classic_locale() { 624 // This funcion will be called once: during build classic _Locale_impl 625 626 // The classic locale contains every facet that belongs to a category. 627 static _Stl_aligned_buffer<_Locale_impl> _Locale_classic_impl_buf; 628 _Locale_impl *classic = new(&_Locale_classic_impl_buf) _Locale_impl("C"); 629 630 locale::facet* classic_facets[] = { 631 0, 632 new collate<char>(1), 633 new ctype<char>(0, false, 1), 634 new codecvt<char, char, mbstate_t>(1), 635 new moneypunct<char, true>(1), 636 new moneypunct<char, false>(1), 637 new numpunct<char>(1), 638 new messages<char>(1), 639 new money_get<char, istreambuf_iterator<char, char_traits<char> > >(1), 640 new money_put<char, ostreambuf_iterator<char, char_traits<char> > >(1), 641 new num_get<char, istreambuf_iterator<char, char_traits<char> > >(1), 642 new num_put<char, ostreambuf_iterator<char, char_traits<char> > >(1), 643 new time_get<char, istreambuf_iterator<char, char_traits<char> > >(1), 644 new time_put<char, ostreambuf_iterator<char, char_traits<char> > >(1), 645 #ifndef _STLP_NO_WCHAR_T 646 new collate<wchar_t>(1), 647 new ctype<wchar_t>(1), 648 new codecvt<wchar_t, char, mbstate_t>(1), 649 new moneypunct<wchar_t, true>(1), 650 new moneypunct<wchar_t, false>(1), 651 new numpunct<wchar_t>(1), 652 new messages<wchar_t>(1), 653 new money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1), 654 new money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1), 655 new num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1), 656 new num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1), 657 new time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1), 658 new time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1), 659 #endif 660 0 661 }; 662 663 const size_t nb_classic_facets = sizeof(classic_facets) / sizeof(locale::facet *); 664 classic->facets_vec.reserve(nb_classic_facets); 665 classic->facets_vec.assign(&classic_facets[0], &classic_facets[0] + nb_classic_facets); 666 667 static locale _Locale_classic(classic); 668 _Stl_classic_locale = &_Locale_classic; 669 670 static locale _Locale_global(classic); 671 _Stl_global_locale = &_Locale_global; 672 } 673 674 // Declarations of (non-template) facets' static data members 675 // size_t locale::id::_S_max = 27; // made before 676 677 locale::id collate<char>::id = { 1 }; 678 locale::id ctype<char>::id = { 2 }; 679 locale::id codecvt<char, char, mbstate_t>::id = { 3 }; 680 locale::id moneypunct<char, true>::id = { 4 }; 681 locale::id moneypunct<char, false>::id = { 5 }; 682 locale::id numpunct<char>::id = { 6 } ; 683 locale::id messages<char>::id = { 7 }; 684 685 #ifndef _STLP_NO_WCHAR_T 686 locale::id collate<wchar_t>::id = { 14 }; 687 locale::id ctype<wchar_t>::id = { 15 }; 688 locale::id codecvt<wchar_t, char, mbstate_t>::id = { 16 }; 689 locale::id moneypunct<wchar_t, true>::id = { 17 } ; 690 locale::id moneypunct<wchar_t, false>::id = { 18 } ; 691 locale::id numpunct<wchar_t>::id = { 19 }; 692 locale::id messages<wchar_t>::id = { 20 }; 693 #endif 694 695 _STLP_DECLSPEC _Locale_impl* _STLP_CALL _get_Locale_impl(_Locale_impl *loc) 696 { 697 _STLP_ASSERT( loc != 0 ); 698 loc->_M_incr(); 699 return loc; 700 } 701 702 void _STLP_CALL _release_Locale_impl(_Locale_impl *& loc) 703 { 704 _STLP_ASSERT( loc != 0 ); 705 if (loc->_M_decr() == 0) { 706 if (*loc != *_Stl_classic_locale) 707 delete loc; 708 else 709 loc->~_Locale_impl(); 710 loc = 0; 711 } 712 } 713 714 _STLP_DECLSPEC _Locale_impl* _STLP_CALL _copy_Nameless_Locale_impl(_Locale_impl *loc) 715 { 716 _STLP_ASSERT( loc != 0 ); 717 _Locale_impl *loc_new = new _Locale_impl(*loc); 718 loc_new->name = _Nameless; 719 return loc_new; 720 } 721 722 /* _GetFacetId implementation have to be here in order to be in the same translation unit 723 * as where id are initialize (in _Stl_loc_assign_ids) */ 724 _STLP_MOVE_TO_PRIV_NAMESPACE 725 726 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<char, istreambuf_iterator<char, char_traits<char> > >*) 727 { return money_get<char, istreambuf_iterator<char, char_traits<char> > >::id; } 728 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<char, ostreambuf_iterator<char, char_traits<char> > >*) 729 { return money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; } 730 #ifndef _STLP_NO_WCHAR_T 731 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*) 732 { return money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; } 733 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*) 734 { return money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; } 735 #endif 736 737 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<char, istreambuf_iterator<char, char_traits<char> > >*) 738 { return num_get<char, istreambuf_iterator<char, char_traits<char> > >::id; } 739 #ifndef _STLP_NO_WCHAR_T 740 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*) 741 { return num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; } 742 #endif 743 744 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<char, ostreambuf_iterator<char, char_traits<char> > >*) 745 { return num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; } 746 #ifndef _STLP_NO_WCHAR_T 747 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*) 748 { return num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; } 749 #endif 750 751 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<char, istreambuf_iterator<char, char_traits<char> > >*) 752 { return time_get<char, istreambuf_iterator<char, char_traits<char> > >::id; } 753 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<char, ostreambuf_iterator<char, char_traits<char> > >*) 754 { return time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; } 755 #ifndef _STLP_NO_WCHAR_T 756 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*) 757 { return time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; } 758 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*) 759 { return time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; } 760 #endif 761 762 _STLP_MOVE_TO_STD_NAMESPACE 763 764 _STLP_END_NAMESPACE 765 766