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