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 char _Nameless[] = "*";
32 
is_C_locale_name(const char * name)33 static inline bool is_C_locale_name (const char* name)
34 { return ((name[0] == 'C') && (name[1] == 0)); }
35 
_get_facet(locale::facet * f)36 locale::facet * _STLP_CALL _get_facet(locale::facet *f)
37 {
38   if (f != 0)
39     f->_M_incr();
40   return f;
41 }
42 
_release_facet(locale::facet * & f)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 
Init()57 _Locale_impl::Init::Init() {
58   if (_M_count()._M_incr() == 1) {
59     _Locale_impl::_S_initialize();
60   }
61 }
62 
~Init()63 _Locale_impl::Init::~Init() {
64   if (_M_count()._M_decr() == 0) {
65     _Locale_impl::_S_uninitialize();
66   }
67 }
68 
_M_count() const69 _Refcount_Base& _Locale_impl::Init::_M_count() const {
70   static _Refcount_Base _S_count(0);
71   return _S_count;
72 }
73 
_Locale_impl(const char * s)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 
_Locale_impl(_Locale_impl const & locimpl)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 
_Locale_impl(size_t n,const char * s)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 
~_Locale_impl()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.)
_S_initialize()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.
_S_uninitialize()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.
_M_throw_bad_cast()116 void _STLP_CALL _Locale_impl::_M_throw_bad_cast() {
117   _STLP_THROW(bad_cast());
118 }
119 
insert(_Locale_impl * from,const locale::id & n)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 
insert(locale::facet * f,const locale::id & n)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. */
insert_ctype_facets(const char * & name,char * buf,_Locale_name_hint * hint)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 
insert_numeric_facets(const char * & name,char * buf,_Locale_name_hint * hint)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 
insert_time_facets(const char * & name,char * buf,_Locale_name_hint * hint)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 
insert_collate_facets(const char * & name,char * buf,_Locale_name_hint * hint)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 
insert_monetary_facets(const char * & name,char * buf,_Locale_name_hint * hint)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 
insert_messages_facets(const char * & name,char * buf,_Locale_name_hint * hint)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 
_Stl_loc_assign_ids()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 
_Stl_get_classic_locale()598 locale* _Stl_get_classic_locale() {
599   static _Locale_impl::Init init;
600   return _Stl_classic_locale;
601 }
602 
_Stl_get_global_locale()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 
make_classic_locale()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 
_get_Locale_impl(_Locale_impl * loc)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 
_release_Locale_impl(_Locale_impl * & loc)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 
_copy_Nameless_Locale_impl(_Locale_impl * loc)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 
_GetFacetId(const money_get<char,istreambuf_iterator<char,char_traits<char>>> *)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; }
_GetFacetId(const money_put<char,ostreambuf_iterator<char,char_traits<char>>> *)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
_GetFacetId(const money_get<wchar_t,istreambuf_iterator<wchar_t,char_traits<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; }
_GetFacetId(const money_put<wchar_t,ostreambuf_iterator<wchar_t,char_traits<wchar_t>>> *)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 
_GetFacetId(const num_get<char,istreambuf_iterator<char,char_traits<char>>> *)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
_GetFacetId(const num_get<wchar_t,istreambuf_iterator<wchar_t,char_traits<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 
_GetFacetId(const num_put<char,ostreambuf_iterator<char,char_traits<char>>> *)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
_GetFacetId(const num_put<wchar_t,ostreambuf_iterator<wchar_t,char_traits<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 
_GetFacetId(const time_get<char,istreambuf_iterator<char,char_traits<char>>> *)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; }
_GetFacetId(const time_put<char,ostreambuf_iterator<char,char_traits<char>>> *)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
_GetFacetId(const time_get<wchar_t,istreambuf_iterator<wchar_t,char_traits<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; }
_GetFacetId(const time_put<wchar_t,ostreambuf_iterator<wchar_t,char_traits<wchar_t>>> *)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