|
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 |
|
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 |