|
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 <hash_map> |
|
21 #include <vector> |
|
22 |
|
23 #include <locale> |
|
24 #include <istream> |
|
25 |
|
26 #include <algorithm> |
|
27 #include <functional> |
|
28 |
|
29 #include "c_locale.h" |
|
30 #include "locale_impl.h" |
|
31 #include "acquire_release.h" |
|
32 |
|
33 _STLP_BEGIN_NAMESPACE |
|
34 |
|
35 //---------------------------------------------------------------------- |
|
36 // ctype_byname<char> |
|
37 |
|
38 _STLP_DECLSPEC ctype_byname<char>::ctype_byname(const char* name, size_t refs, _Locale_name_hint* hint) : |
|
39 ctype<char>( 0, false, refs), |
|
40 _M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) { |
|
41 ctype<char>::_M_ctype_table = _M_byname_table; |
|
42 if (!_M_ctype) |
|
43 locale::_M_throw_runtime_error(); |
|
44 |
|
45 // We have to do this, instead of just pointer twiddling, because |
|
46 // ctype_base::mask isn't the same type as _Locale_mask_t. |
|
47 |
|
48 const _Locale_mask_t* p = _Locale_ctype_table(_M_ctype); |
|
49 |
|
50 if (!p) |
|
51 locale::_M_throw_runtime_error(); |
|
52 |
|
53 for (size_t i = 0; i < table_size; ++i) { |
|
54 _Locale_mask_t __m = p[i]; |
|
55 if (__m & (upper | lower)) |
|
56 __m |= alpha; |
|
57 _M_byname_table[i] = ctype_base::mask(__m); |
|
58 } |
|
59 } |
|
60 |
|
61 _STLP_DECLSPEC ctype_byname<char>::~ctype_byname() |
|
62 { _STLP_PRIV __release_ctype(_M_ctype); } |
|
63 |
|
64 _STLP_DECLSPEC char ctype_byname<char>::do_toupper(char c) const |
|
65 { return (char)_Locale_toupper(_M_ctype, c); } |
|
66 |
|
67 _STLP_DECLSPEC char ctype_byname<char>::do_tolower(char c) const |
|
68 { return (char)_Locale_tolower(_M_ctype, c); } |
|
69 |
|
70 _STLP_DECLSPEC const char* |
|
71 ctype_byname<char>::do_toupper(char* first, const char* last) const { |
|
72 for ( ; first != last ; ++first) |
|
73 *first = (char)_Locale_toupper(_M_ctype, *first); |
|
74 return last; |
|
75 } |
|
76 |
|
77 _STLP_DECLSPEC const char* |
|
78 ctype_byname<char>::do_tolower(char* first, const char* last) const { |
|
79 for ( ; first != last ; ++first) |
|
80 *first = (char)_Locale_tolower(_M_ctype, *first); |
|
81 return last; |
|
82 } |
|
83 |
|
84 |
|
85 // Some helper functions used in ctype<>::scan_is and scan_is_not. |
|
86 #if !defined (_STLP_NO_WCHAR_T) |
|
87 |
|
88 _STLP_MOVE_TO_PRIV_NAMESPACE |
|
89 |
|
90 // ctype_byname<wchar_t> |
|
91 |
|
92 struct _Ctype_byname_w_is_mask { |
|
93 typedef wchar_t argument_type; |
|
94 typedef bool result_type; |
|
95 |
|
96 /* ctype_base::mask*/ int M; |
|
97 _Locale_ctype* M_ctp; |
|
98 |
|
99 _Ctype_byname_w_is_mask(/* ctype_base::mask */ int m, _Locale_ctype* c) : M((int)m), M_ctp(c) {} |
|
100 bool operator()(wchar_t c) const |
|
101 { return (M & _Locale_wchar_ctype(M_ctp, c, M)) != 0; } |
|
102 }; |
|
103 |
|
104 _STLP_MOVE_TO_STD_NAMESPACE |
|
105 |
|
106 _STLP_DECLSPEC ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
107 : ctype<wchar_t>(refs), |
|
108 _M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) { |
|
109 if (!_M_ctype) |
|
110 locale::_M_throw_runtime_error(); |
|
111 } |
|
112 |
|
113 _STLP_DECLSPEC ctype_byname<wchar_t>::~ctype_byname() |
|
114 { _STLP_PRIV __release_ctype(_M_ctype); } |
|
115 |
|
116 _STLP_DECLSPEC bool ctype_byname<wchar_t>::do_is(ctype_base::mask m, wchar_t c) const |
|
117 { return (m & _Locale_wchar_ctype(_M_ctype, c, m)) != 0; } |
|
118 |
|
119 _STLP_DECLSPEC const wchar_t* |
|
120 ctype_byname<wchar_t>::do_is(const wchar_t* low, const wchar_t* high, |
|
121 ctype_base::mask * m) const { |
|
122 ctype_base::mask all_bits = ctype_base::mask( |
|
123 ctype_base::space | |
|
124 ctype_base::print | |
|
125 ctype_base::cntrl | |
|
126 ctype_base::upper | |
|
127 ctype_base::lower | |
|
128 ctype_base::alpha | |
|
129 ctype_base::digit | |
|
130 ctype_base::punct | |
|
131 ctype_base::xdigit); |
|
132 |
|
133 for ( ; low < high; ++low, ++m) |
|
134 *m = ctype_base::mask (_Locale_wchar_ctype(_M_ctype, *low, all_bits)); |
|
135 return high; |
|
136 } |
|
137 |
|
138 _STLP_DECLSPEC const wchar_t* |
|
139 ctype_byname<wchar_t> |
|
140 ::do_scan_is(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const |
|
141 { return find_if(low, high, _STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype)); } |
|
142 |
|
143 _STLP_DECLSPEC const wchar_t* |
|
144 ctype_byname<wchar_t> |
|
145 ::do_scan_not(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const |
|
146 { return find_if(low, high, not1(_STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype))); } |
|
147 |
|
148 _STLP_DECLSPEC wchar_t ctype_byname<wchar_t>::do_toupper(wchar_t c) const |
|
149 { return _Locale_wchar_toupper(_M_ctype, c); } |
|
150 |
|
151 _STLP_DECLSPEC const wchar_t* |
|
152 ctype_byname<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const { |
|
153 for ( ; low < high; ++low) |
|
154 *low = _Locale_wchar_toupper(_M_ctype, *low); |
|
155 return high; |
|
156 } |
|
157 |
|
158 _STLP_DECLSPEC wchar_t ctype_byname<wchar_t>::do_tolower(wchar_t c) const |
|
159 { return _Locale_wchar_tolower(_M_ctype, c); } |
|
160 |
|
161 _STLP_DECLSPEC const wchar_t* |
|
162 ctype_byname<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const { |
|
163 for ( ; low < high; ++low) |
|
164 *low = _Locale_wchar_tolower(_M_ctype, *low); |
|
165 return high; |
|
166 } |
|
167 |
|
168 #endif /* WCHAR_T */ |
|
169 |
|
170 // collate_byname<char> |
|
171 _STLP_DECLSPEC collate_byname<char>::collate_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
172 : collate<char>(refs), |
|
173 _M_collate(_STLP_PRIV __acquire_collate(name, hint)) { |
|
174 if (!_M_collate) |
|
175 locale::_M_throw_runtime_error(); |
|
176 } |
|
177 |
|
178 _STLP_DECLSPEC collate_byname<char>::~collate_byname() |
|
179 { _STLP_PRIV __release_collate(_M_collate); } |
|
180 |
|
181 _STLP_DECLSPEC int collate_byname<char>::do_compare(const char* __low1, |
|
182 const char* __high1, |
|
183 const char* __low2, |
|
184 const char* __high2) const { |
|
185 return _Locale_strcmp(_M_collate, |
|
186 __low1, __high1 - __low1, |
|
187 __low2, __high2 - __low2); |
|
188 } |
|
189 |
|
190 _STLP_DECLSPEC collate_byname<char>::string_type |
|
191 collate_byname<char>::do_transform(const char* low, const char* high) const { |
|
192 if (low == high) |
|
193 return string_type(); |
|
194 |
|
195 size_t n = _Locale_strxfrm(_M_collate, NULL, 0, low, high - low); |
|
196 |
|
197 // NOT PORTABLE. What we're doing relies on internal details of the |
|
198 // string implementation. (Contiguity of string elements and presence |
|
199 // of trailing zero.) |
|
200 string_type buf(n, 0); |
|
201 _Locale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low); |
|
202 return buf; |
|
203 } |
|
204 |
|
205 |
|
206 #if !defined (_STLP_NO_WCHAR_T) |
|
207 |
|
208 // collate_byname<wchar_t> |
|
209 |
|
210 _STLP_DECLSPEC collate_byname<wchar_t>::collate_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
211 : collate<wchar_t>(refs), |
|
212 _M_collate(_STLP_PRIV __acquire_collate(name, hint)) { |
|
213 if (!_M_collate) |
|
214 locale::_M_throw_runtime_error(); |
|
215 } |
|
216 |
|
217 _STLP_DECLSPEC collate_byname<wchar_t>::~collate_byname() |
|
218 { _STLP_PRIV __release_collate(_M_collate); } |
|
219 |
|
220 _STLP_DECLSPEC int collate_byname<wchar_t>::do_compare(const wchar_t* low1, |
|
221 const wchar_t* high1, |
|
222 const wchar_t* low2, |
|
223 const wchar_t* high2) const { |
|
224 return _Locale_strwcmp(_M_collate, |
|
225 low1, high1 - low1, |
|
226 low2, high2 - low2); |
|
227 } |
|
228 |
|
229 _STLP_DECLSPEC collate_byname<wchar_t>::string_type |
|
230 collate_byname<wchar_t>::do_transform(const wchar_t* low, |
|
231 const wchar_t* high) const { |
|
232 if (low == high) |
|
233 return string_type(); |
|
234 |
|
235 size_t n = _Locale_strwxfrm(_M_collate, NULL, 0, low, high - low); |
|
236 |
|
237 // NOT PORTABLE. What we're doing relies on internal details of the |
|
238 // string implementation. (Contiguity of string elements and presence |
|
239 // of trailing zero.) |
|
240 string_type buf(n, 0); |
|
241 _Locale_strwxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low); |
|
242 return buf; |
|
243 } |
|
244 |
|
245 #endif /* _STLP_NO_WCHAR_T */ |
|
246 |
|
247 _STLP_END_NAMESPACE |
|
248 |
|
249 #if !defined (_STLP_NO_MBSTATE_T) |
|
250 |
|
251 _STLP_BEGIN_NAMESPACE |
|
252 |
|
253 //---------------------------------------------------------------------- |
|
254 // codecvt_byname<char> |
|
255 |
|
256 _STLP_DECLSPEC codecvt_byname<char, char, mbstate_t> |
|
257 ::codecvt_byname(const char* /* name */, size_t refs) |
|
258 : codecvt<char, char, mbstate_t>(refs) {} |
|
259 |
|
260 _STLP_DECLSPEC codecvt_byname<char, char, mbstate_t>::~codecvt_byname() {} |
|
261 |
|
262 |
|
263 # if !defined (_STLP_NO_WCHAR_T) |
|
264 |
|
265 //---------------------------------------------------------------------- |
|
266 // codecvt_byname<wchar_t> |
|
267 _STLP_DECLSPEC codecvt_byname<wchar_t, char, mbstate_t> |
|
268 ::codecvt_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
269 : codecvt<wchar_t, char, mbstate_t>(refs), |
|
270 _M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) { |
|
271 if (!_M_ctype) |
|
272 locale::_M_throw_runtime_error(); |
|
273 } |
|
274 |
|
275 _STLP_DECLSPEC codecvt_byname<wchar_t, char, mbstate_t>::~codecvt_byname() |
|
276 { _STLP_PRIV __release_ctype(_M_ctype); } |
|
277 |
|
278 _STLP_DECLSPEC codecvt<wchar_t, char, mbstate_t>::result |
|
279 codecvt_byname<wchar_t, char, mbstate_t> |
|
280 ::do_out(state_type& state, |
|
281 const wchar_t* from, |
|
282 const wchar_t* from_end, |
|
283 const wchar_t*& from_next, |
|
284 char* to, |
|
285 char* to_limit, |
|
286 char*& to_next) const { |
|
287 while (from != from_end) { |
|
288 size_t chars_stored = _Locale_wctomb(_M_ctype, |
|
289 to, to_limit - to, *from, |
|
290 &state); |
|
291 if (chars_stored == (size_t) -1) { |
|
292 from_next = from; |
|
293 to_next = to; |
|
294 return error; |
|
295 } |
|
296 else if (chars_stored == (size_t) -2) { |
|
297 from_next = from; |
|
298 to_next = to; |
|
299 return partial; |
|
300 } |
|
301 |
|
302 ++from; |
|
303 to += chars_stored; |
|
304 } |
|
305 |
|
306 from_next = from; |
|
307 to_next = to; |
|
308 return ok; |
|
309 } |
|
310 |
|
311 _STLP_DECLSPEC codecvt<wchar_t, char, mbstate_t>::result |
|
312 codecvt_byname<wchar_t, char, mbstate_t> |
|
313 ::do_in(state_type& state, |
|
314 const extern_type* from, |
|
315 const extern_type* from_end, |
|
316 const extern_type*& from_next, |
|
317 intern_type* to, |
|
318 intern_type* , |
|
319 intern_type*& to_next) const { |
|
320 while (from != from_end) { |
|
321 size_t chars_read = _Locale_mbtowc(_M_ctype, |
|
322 to, from, from_end - from, |
|
323 &state); |
|
324 if (chars_read == (size_t) -1) { |
|
325 from_next = from; |
|
326 to_next = to; |
|
327 return error; |
|
328 } |
|
329 |
|
330 if (chars_read == (size_t) -2) { |
|
331 from_next = from; |
|
332 to_next = to; |
|
333 return partial; |
|
334 } |
|
335 |
|
336 from += chars_read; |
|
337 to++; |
|
338 } |
|
339 |
|
340 from_next = from; |
|
341 to_next = to; |
|
342 return ok; |
|
343 } |
|
344 |
|
345 _STLP_DECLSPEC codecvt<wchar_t, char, mbstate_t>::result |
|
346 codecvt_byname<wchar_t, char, mbstate_t> |
|
347 ::do_unshift(state_type& state, |
|
348 extern_type* to, |
|
349 extern_type* to_limit, |
|
350 extern_type*& to_next) const { |
|
351 to_next = to; |
|
352 size_t result = _Locale_unshift(_M_ctype, &state, |
|
353 to, to_limit - to, &to_next); |
|
354 if (result == (size_t) -1) |
|
355 return error; |
|
356 else if (result == (size_t) -2) |
|
357 return partial; |
|
358 else |
|
359 # if defined (__ISCPP__) |
|
360 return /*to_next == to ? noconv :*/ ok; |
|
361 # else |
|
362 return to_next == to ? noconv : ok; |
|
363 # endif |
|
364 } |
|
365 |
|
366 _STLP_DECLSPEC int |
|
367 codecvt_byname<wchar_t, char, mbstate_t>::do_encoding() const _STLP_NOTHROW { |
|
368 if (_Locale_is_stateless(_M_ctype)) { |
|
369 int max_width = _Locale_mb_cur_max(_M_ctype); |
|
370 int min_width = _Locale_mb_cur_min(_M_ctype); |
|
371 return min_width == max_width ? min_width : 0; |
|
372 } |
|
373 else |
|
374 return -1; |
|
375 } |
|
376 |
|
377 _STLP_DECLSPEC bool codecvt_byname<wchar_t, char, mbstate_t> |
|
378 ::do_always_noconv() const _STLP_NOTHROW { |
|
379 return false; |
|
380 } |
|
381 |
|
382 _STLP_DECLSPEC int |
|
383 codecvt_byname<wchar_t, char, mbstate_t>::do_length(const state_type&, |
|
384 const extern_type* from, const extern_type* end, |
|
385 size_t mx) const |
|
386 { return (int)(min) ((size_t) (end - from), mx); } |
|
387 |
|
388 _STLP_DECLSPEC int |
|
389 codecvt_byname<wchar_t, char, mbstate_t>::do_max_length() const _STLP_NOTHROW |
|
390 { return _Locale_mb_cur_max(_M_ctype); } |
|
391 # endif |
|
392 |
|
393 _STLP_END_NAMESPACE |
|
394 |
|
395 #endif /* MBSTATE_T */ |
|
396 |
|
397 _STLP_BEGIN_NAMESPACE |
|
398 |
|
399 // numpunct_byname<char> |
|
400 _STLP_DECLSPEC numpunct_byname<char>::numpunct_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
401 : numpunct<char>(refs), |
|
402 _M_numeric(_STLP_PRIV __acquire_numeric(name, hint)) { |
|
403 if (!_M_numeric) |
|
404 locale::_M_throw_runtime_error(); |
|
405 |
|
406 _M_truename = _Locale_true(_M_numeric); |
|
407 _M_falsename = _Locale_false(_M_numeric); |
|
408 } |
|
409 |
|
410 _STLP_DECLSPEC numpunct_byname<char>::~numpunct_byname() |
|
411 { _STLP_PRIV __release_numeric(_M_numeric); } |
|
412 |
|
413 _STLP_DECLSPEC char numpunct_byname<char>::do_decimal_point() const |
|
414 { return _Locale_decimal_point(_M_numeric); } |
|
415 |
|
416 _STLP_DECLSPEC char numpunct_byname<char>::do_thousands_sep() const |
|
417 { return _Locale_thousands_sep(_M_numeric); } |
|
418 |
|
419 _STLP_DECLSPEC string numpunct_byname<char>::do_grouping() const { |
|
420 const char * __grouping = _Locale_grouping(_M_numeric); |
|
421 if (__grouping != NULL && __grouping[0] == CHAR_MAX) |
|
422 __grouping = ""; |
|
423 return __grouping; |
|
424 } |
|
425 |
|
426 //---------------------------------------------------------------------- |
|
427 // numpunct<wchar_t> |
|
428 |
|
429 #if !defined (_STLP_NO_WCHAR_T) |
|
430 |
|
431 // numpunct_byname<wchar_t> |
|
432 |
|
433 _STLP_DECLSPEC numpunct_byname<wchar_t>::numpunct_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
434 : numpunct<wchar_t>(refs), |
|
435 _M_numeric(_STLP_PRIV __acquire_numeric(name, hint)) { |
|
436 if (!_M_numeric) |
|
437 locale::_M_throw_runtime_error(); |
|
438 |
|
439 const char* truename = _Locale_true(_M_numeric); |
|
440 const char* falsename = _Locale_false(_M_numeric); |
|
441 _M_truename.resize(strlen(truename)); |
|
442 _M_falsename.resize(strlen(falsename)); |
|
443 copy(truename, truename + strlen(truename), _M_truename.begin()); |
|
444 copy(falsename, falsename + strlen(falsename), _M_falsename.begin()); |
|
445 } |
|
446 |
|
447 _STLP_DECLSPEC numpunct_byname<wchar_t>::~numpunct_byname() |
|
448 { _STLP_PRIV __release_numeric(_M_numeric); } |
|
449 |
|
450 _STLP_DECLSPEC wchar_t numpunct_byname<wchar_t>::do_decimal_point() const |
|
451 { return (wchar_t) _Locale_decimal_point(_M_numeric); } |
|
452 |
|
453 _STLP_DECLSPEC wchar_t numpunct_byname<wchar_t>::do_thousands_sep() const |
|
454 { return (wchar_t) _Locale_thousands_sep(_M_numeric); } |
|
455 |
|
456 _STLP_DECLSPEC string numpunct_byname<wchar_t>::do_grouping() const { |
|
457 const char * __grouping = _Locale_grouping(_M_numeric); |
|
458 if (__grouping != NULL && __grouping[0] == CHAR_MAX) |
|
459 __grouping = ""; |
|
460 return __grouping; |
|
461 } |
|
462 |
|
463 #endif |
|
464 |
|
465 _STLP_MOVE_TO_PRIV_NAMESPACE |
|
466 |
|
467 static void _Init_monetary_formats(money_base::pattern& pos_format, |
|
468 money_base::pattern& neg_format, |
|
469 _Locale_monetary * monetary) { |
|
470 switch (_Locale_p_sign_posn(monetary)) { |
|
471 case 0: // Parentheses surround the quantity and currency_symbol |
|
472 case 1: // The sign string precedes the quantity and currency_symbol |
|
473 pos_format.field[0] = (char) money_base::sign; |
|
474 if (_Locale_p_cs_precedes(monetary)) { |
|
475 // 1 if currency_symbol precedes a positive value |
|
476 pos_format.field[1] = (char) money_base::symbol; |
|
477 if (_Locale_p_sep_by_space(monetary)) { |
|
478 // a space separates currency_symbol from a positive value. |
|
479 pos_format.field[2] = (char) money_base::space; |
|
480 pos_format.field[3] = (char) money_base::value; |
|
481 } else { |
|
482 // a space not separates currency_symbol from a positive value. |
|
483 pos_format.field[2] = (char) money_base::value; |
|
484 pos_format.field[3] = (char) money_base::none; |
|
485 } |
|
486 } else { |
|
487 // 0 if currency_symbol succeeds a positive value |
|
488 pos_format.field[1] = (char) money_base::value; |
|
489 if (_Locale_p_sep_by_space(monetary)) { |
|
490 // a space separates currency_symbol from a positive value. |
|
491 pos_format.field[2] = (char) money_base::space; |
|
492 pos_format.field[3] = (char) money_base::symbol; |
|
493 } else { |
|
494 // a space not separates currency_symbol from a positive value. |
|
495 pos_format.field[2] = (char) money_base::symbol; |
|
496 pos_format.field[3] = (char) money_base::none; |
|
497 } |
|
498 } |
|
499 break; |
|
500 case 2: // The sign string succeeds the quantity and currency_symbol. |
|
501 if (_Locale_p_cs_precedes(monetary)) { |
|
502 // 1 if currency_symbol precedes a positive value |
|
503 pos_format.field[0] = (char) money_base::symbol; |
|
504 if (_Locale_p_sep_by_space(monetary)) { |
|
505 // a space separates currency_symbol from a positive value. |
|
506 pos_format.field[1] = (char) money_base::space; |
|
507 pos_format.field[2] = (char) money_base::value; |
|
508 pos_format.field[3] = (char) money_base::sign; |
|
509 } else { |
|
510 // a space not separates currency_symbol from a positive value. |
|
511 pos_format.field[1] = (char) money_base::value; |
|
512 pos_format.field[2] = (char) money_base::sign; |
|
513 pos_format.field[3] = (char) money_base::none; |
|
514 } |
|
515 } else { |
|
516 // 0 if currency_symbol succeeds a positive value |
|
517 pos_format.field[0] = (char) money_base::value; |
|
518 if (_Locale_p_sep_by_space(monetary)) { |
|
519 // a space separates currency_symbol from a positive value. |
|
520 pos_format.field[1] = (char) money_base::space; |
|
521 pos_format.field[2] = (char) money_base::symbol; |
|
522 pos_format.field[3] = (char) money_base::sign; |
|
523 } else { |
|
524 // a space not separates currency_symbol from a positive value. |
|
525 pos_format.field[1] = (char) money_base::symbol; |
|
526 pos_format.field[2] = (char) money_base::sign; |
|
527 pos_format.field[3] = (char) money_base::none; |
|
528 } |
|
529 } |
|
530 break; |
|
531 case 3: // The sign string immediately precedes the currency_symbol. |
|
532 if (_Locale_p_cs_precedes(monetary)) { |
|
533 // 1 if currency_symbol precedes a positive value |
|
534 pos_format.field[0] = (char) money_base::sign; |
|
535 pos_format.field[1] = (char) money_base::symbol; |
|
536 if (_Locale_p_sep_by_space(monetary)) { |
|
537 // a space separates currency_symbol from a positive value. |
|
538 pos_format.field[2] = (char) money_base::space; |
|
539 pos_format.field[3] = (char) money_base::value; |
|
540 } else { |
|
541 // a space not separates currency_symbol from a positive value. |
|
542 pos_format.field[2] = (char) money_base::value; |
|
543 pos_format.field[3] = (char) money_base::none; |
|
544 } |
|
545 } else { |
|
546 // 0 if currency_symbol succeeds a positive value |
|
547 pos_format.field[0] = (char) money_base::value; |
|
548 pos_format.field[1] = (char) money_base::sign; |
|
549 pos_format.field[2] = (char) money_base::symbol; |
|
550 pos_format.field[3] = (char) money_base::none; |
|
551 } |
|
552 break; |
|
553 case 4: // The sign string immediately succeeds the currency_symbol. |
|
554 default: |
|
555 if (_Locale_p_cs_precedes(monetary)) { |
|
556 // 1 if currency_symbol precedes a positive value |
|
557 pos_format.field[0] = (char) money_base::symbol; |
|
558 pos_format.field[1] = (char) money_base::sign; |
|
559 pos_format.field[2] = (char) money_base::value; |
|
560 pos_format.field[3] = (char) money_base::none; |
|
561 } else { |
|
562 // 0 if currency_symbol succeeds a positive value |
|
563 pos_format.field[0] = (char) money_base::value; |
|
564 if (_Locale_p_sep_by_space(monetary)) { |
|
565 // a space separates currency_symbol from a positive value. |
|
566 pos_format.field[1] = (char) money_base::space; |
|
567 pos_format.field[2] = (char) money_base::symbol; |
|
568 pos_format.field[3] = (char) money_base::sign; |
|
569 } else { |
|
570 // a space not separates currency_symbol from a positive value. |
|
571 pos_format.field[1] = (char) money_base::symbol; |
|
572 pos_format.field[2] = (char) money_base::sign; |
|
573 pos_format.field[3] = (char) money_base::none; |
|
574 } |
|
575 } |
|
576 break; |
|
577 } |
|
578 |
|
579 switch (_Locale_n_sign_posn(monetary)) { |
|
580 case 0: // Parentheses surround the quantity and currency_symbol |
|
581 case 1: // The sign string precedes the quantity and currency_symbol |
|
582 neg_format.field[0] = (char) money_base::sign; |
|
583 if (_Locale_n_cs_precedes(monetary)) { |
|
584 // 1 if currency_symbol precedes a negative value |
|
585 neg_format.field[1] = (char) money_base::symbol; |
|
586 if (_Locale_n_sep_by_space(monetary)) { |
|
587 // a space separates currency_symbol from a negative value. |
|
588 neg_format.field[2] = (char) money_base::space; |
|
589 neg_format.field[3] = (char) money_base::value; |
|
590 } else { |
|
591 // a space not separates currency_symbol from a negative value. |
|
592 neg_format.field[2] = (char) money_base::value; |
|
593 neg_format.field[3] = (char) money_base::none; |
|
594 } |
|
595 } else { |
|
596 // 0 if currency_symbol succeeds a negative value |
|
597 neg_format.field[1] = (char) money_base::value; |
|
598 if (_Locale_n_sep_by_space(monetary)) { |
|
599 // a space separates currency_symbol from a negative value. |
|
600 neg_format.field[2] = (char) money_base::space; |
|
601 neg_format.field[3] = (char) money_base::symbol; |
|
602 } else { |
|
603 // a space not separates currency_symbol from a negative value. |
|
604 neg_format.field[2] = (char) money_base::symbol; |
|
605 neg_format.field[3] = (char) money_base::none; |
|
606 } |
|
607 } |
|
608 break; |
|
609 case 2: // The sign string succeeds the quantity and currency_symbol. |
|
610 if (_Locale_n_cs_precedes(monetary)) { |
|
611 // 1 if currency_symbol precedes a negative value |
|
612 neg_format.field[0] = (char) money_base::symbol; |
|
613 if (_Locale_n_sep_by_space(monetary)) { |
|
614 // a space separates currency_symbol from a negative value. |
|
615 neg_format.field[1] = (char) money_base::space; |
|
616 neg_format.field[2] = (char) money_base::value; |
|
617 neg_format.field[3] = (char) money_base::sign; |
|
618 } else { |
|
619 // a space not separates currency_symbol from a negative value. |
|
620 neg_format.field[1] = (char) money_base::value; |
|
621 neg_format.field[2] = (char) money_base::sign; |
|
622 neg_format.field[3] = (char) money_base::none; |
|
623 } |
|
624 } else { |
|
625 // 0 if currency_symbol succeeds a negative value |
|
626 neg_format.field[0] = (char) money_base::value; |
|
627 if (_Locale_n_sep_by_space(monetary)) { |
|
628 // a space separates currency_symbol from a negative value. |
|
629 neg_format.field[1] = (char) money_base::space; |
|
630 neg_format.field[2] = (char) money_base::symbol; |
|
631 neg_format.field[3] = (char) money_base::sign; |
|
632 } else { |
|
633 // a space not separates currency_symbol from a negative value. |
|
634 neg_format.field[1] = (char) money_base::symbol; |
|
635 neg_format.field[2] = (char) money_base::sign; |
|
636 neg_format.field[3] = (char) money_base::none; |
|
637 } |
|
638 } |
|
639 break; |
|
640 case 3: // The sign string immediately precedes the currency_symbol. |
|
641 if (_Locale_n_cs_precedes(monetary)) { |
|
642 // 1 if currency_symbol precedes a negative value |
|
643 neg_format.field[0] = (char) money_base::sign; |
|
644 neg_format.field[1] = (char) money_base::symbol; |
|
645 if (_Locale_n_sep_by_space(monetary)) { |
|
646 // a space separates currency_symbol from a negative value. |
|
647 neg_format.field[2] = (char) money_base::space; |
|
648 neg_format.field[3] = (char) money_base::value; |
|
649 } else { |
|
650 // a space not separates currency_symbol from a negative value. |
|
651 neg_format.field[2] = (char) money_base::value; |
|
652 neg_format.field[3] = (char) money_base::none; |
|
653 } |
|
654 } else { |
|
655 // 0 if currency_symbol succeeds a negative value |
|
656 neg_format.field[0] = (char) money_base::value; |
|
657 neg_format.field[1] = (char) money_base::sign; |
|
658 neg_format.field[2] = (char) money_base::symbol; |
|
659 neg_format.field[3] = (char) money_base::none; |
|
660 } |
|
661 break; |
|
662 case 4: // The sign string immediately succeeds the currency_symbol. |
|
663 default: |
|
664 if (_Locale_n_cs_precedes(monetary)) { |
|
665 // 1 if currency_symbol precedes a negative value |
|
666 neg_format.field[0] = (char) money_base::symbol; |
|
667 neg_format.field[1] = (char) money_base::sign; |
|
668 neg_format.field[2] = (char) money_base::value; |
|
669 neg_format.field[3] = (char) money_base::none; |
|
670 } else { |
|
671 // 0 if currency_symbol succeeds a negative value |
|
672 neg_format.field[0] = (char) money_base::value; |
|
673 if (_Locale_n_sep_by_space(monetary)) { |
|
674 // a space separates currency_symbol from a negative value. |
|
675 neg_format.field[1] = (char) money_base::space; |
|
676 neg_format.field[2] = (char) money_base::symbol; |
|
677 neg_format.field[3] = (char) money_base::sign; |
|
678 } else { |
|
679 // a space not separates currency_symbol from a negative value. |
|
680 neg_format.field[1] = (char) money_base::symbol; |
|
681 neg_format.field[2] = (char) money_base::sign; |
|
682 neg_format.field[3] = (char) money_base::none; |
|
683 } |
|
684 } |
|
685 break; |
|
686 } |
|
687 } |
|
688 |
|
689 // international variant of monetary |
|
690 |
|
691 /* |
|
692 * int_curr_symbol |
|
693 * |
|
694 * The international currency symbol. The operand is a four-character |
|
695 * string, with the first three characters containing the alphabetic |
|
696 * international currency symbol in accordance with those specified |
|
697 * in the ISO 4217 specification. The fourth character is the character used |
|
698 * to separate the international currency symbol from the monetary quantity. |
|
699 * |
|
700 * (http://www.opengroup.org/onlinepubs/7990989775/xbd/locale.html) |
|
701 */ |
|
702 |
|
703 /* |
|
704 * Standards are unclear in the usage of international currency |
|
705 * and monetary formats. |
|
706 * But I am expect that international currency symbol should be the first |
|
707 * (not depends upon where currency symbol situated in the national |
|
708 * format). |
|
709 * |
|
710 * If this isn't so, let's see: |
|
711 * 1 234.56 RUR |
|
712 * GBP 1,234.56 |
|
713 * USD 1,234.56 |
|
714 * The situation really is worse than you see above: |
|
715 * RUR typed wrong here---it prints '1 234.56 RUR ' (see space after RUR). |
|
716 * This is due to intl_fmp.curr_symbol() == "RUR ". (see reference in comments |
|
717 * above). |
|
718 * |
|
719 */ |
|
720 |
|
721 static void _Init_monetary_formats_int(money_base::pattern& pos_format, |
|
722 money_base::pattern& neg_format, |
|
723 _Locale_monetary * monetary) |
|
724 { |
|
725 pos_format.field[0] = (char) money_base::symbol; |
|
726 // pos_format.field[1] = (char) money_base::space; |
|
727 |
|
728 switch (_Locale_p_sign_posn(monetary)) { |
|
729 case 0: // Parentheses surround the quantity and currency_symbol |
|
730 case 1: // The sign string precedes the quantity and currency_symbol |
|
731 pos_format.field[1] = (char) money_base::sign; |
|
732 pos_format.field[2] = (char) money_base::value; |
|
733 break; |
|
734 case 2: // The sign string succeeds the quantity and currency_symbol. |
|
735 pos_format.field[1] = (char) money_base::value; |
|
736 pos_format.field[2] = (char) money_base::sign; |
|
737 break; |
|
738 case 3: // The sign string immediately precedes the currency_symbol. |
|
739 case 4: // The sign string immediately succeeds the currency_symbol. |
|
740 default: |
|
741 if (_Locale_p_cs_precedes(monetary)) { |
|
742 // 1 if currency_symbol precedes a positive value |
|
743 pos_format.field[1] = (char) money_base::sign; |
|
744 pos_format.field[2] = (char) money_base::value; |
|
745 } else { |
|
746 // 0 if currency_symbol succeeds a positive value |
|
747 pos_format.field[1] = (char) money_base::value; |
|
748 pos_format.field[2] = (char) money_base::sign; |
|
749 } |
|
750 break; |
|
751 } |
|
752 pos_format.field[3] = (char) money_base::none; |
|
753 |
|
754 neg_format.field[0] = (char) money_base::symbol; |
|
755 // neg_format.field[1] = (char) money_base::space; |
|
756 |
|
757 switch (_Locale_n_sign_posn(monetary)) { |
|
758 case 0: // Parentheses surround the quantity and currency_symbol |
|
759 case 1: // The sign string precedes the quantity and currency_symbol |
|
760 neg_format.field[1] = (char) money_base::sign; |
|
761 neg_format.field[2] = (char) money_base::value; |
|
762 break; |
|
763 case 2: // The sign string succeeds the quantity and currency_symbol. |
|
764 neg_format.field[1] = (char) money_base::value; |
|
765 neg_format.field[2] = (char) money_base::sign; |
|
766 break; |
|
767 case 3: // The sign string immediately precedes the currency_symbol. |
|
768 case 4: // The sign string immediately succeeds the currency_symbol. |
|
769 default: |
|
770 if (_Locale_n_cs_precedes(monetary)) { |
|
771 // 1 if currency_symbol precedes a negative value |
|
772 neg_format.field[1] = (char) money_base::sign; |
|
773 neg_format.field[2] = (char) money_base::value; |
|
774 } else { |
|
775 // 0 if currency_symbol succeeds a negative value |
|
776 neg_format.field[1] = (char) money_base::value; |
|
777 neg_format.field[2] = (char) money_base::sign; |
|
778 } |
|
779 break; |
|
780 } |
|
781 neg_format.field[3] = (char) money_base::none; |
|
782 } |
|
783 |
|
784 _STLP_MOVE_TO_STD_NAMESPACE |
|
785 |
|
786 // |
|
787 // moneypunct_byname<> |
|
788 // |
|
789 _STLP_DECLSPEC moneypunct_byname<char, true>::moneypunct_byname(const char * name, |
|
790 size_t refs, _Locale_name_hint* hint): |
|
791 moneypunct<char, true>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) { |
|
792 if (!_M_monetary) |
|
793 locale::_M_throw_runtime_error(); |
|
794 _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary); |
|
795 } |
|
796 |
|
797 _STLP_DECLSPEC moneypunct_byname<char, true>::~moneypunct_byname() |
|
798 { _STLP_PRIV __release_monetary(_M_monetary); } |
|
799 |
|
800 _STLP_DECLSPEC char moneypunct_byname<char, true>::do_decimal_point() const |
|
801 { return _Locale_mon_decimal_point(_M_monetary); } |
|
802 |
|
803 _STLP_DECLSPEC char moneypunct_byname<char, true>::do_thousands_sep() const |
|
804 { return _Locale_mon_thousands_sep(_M_monetary); } |
|
805 |
|
806 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_grouping() const |
|
807 { return _Locale_mon_grouping(_M_monetary); } |
|
808 |
|
809 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_curr_symbol() const |
|
810 { return _Locale_int_curr_symbol(_M_monetary); } |
|
811 |
|
812 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_positive_sign() const |
|
813 { return _Locale_positive_sign(_M_monetary); } |
|
814 |
|
815 _STLP_DECLSPEC string moneypunct_byname<char, true>::do_negative_sign() const |
|
816 { return _Locale_negative_sign(_M_monetary); } |
|
817 |
|
818 _STLP_DECLSPEC int moneypunct_byname<char, true>::do_frac_digits() const |
|
819 { return _Locale_int_frac_digits(_M_monetary); } |
|
820 |
|
821 _STLP_DECLSPEC moneypunct_byname<char, false>::moneypunct_byname(const char * name, |
|
822 size_t refs, _Locale_name_hint* hint): |
|
823 moneypunct<char, false>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) { |
|
824 if (!_M_monetary) |
|
825 locale::_M_throw_runtime_error(); |
|
826 _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary); |
|
827 } |
|
828 |
|
829 _STLP_DECLSPEC moneypunct_byname<char, false>::~moneypunct_byname() |
|
830 { _STLP_PRIV __release_monetary(_M_monetary); } |
|
831 |
|
832 _STLP_DECLSPEC char moneypunct_byname<char, false>::do_decimal_point() const |
|
833 { return _Locale_mon_decimal_point(_M_monetary); } |
|
834 |
|
835 _STLP_DECLSPEC char moneypunct_byname<char, false>::do_thousands_sep() const |
|
836 { return _Locale_mon_thousands_sep(_M_monetary); } |
|
837 |
|
838 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_grouping() const |
|
839 { return _Locale_mon_grouping(_M_monetary); } |
|
840 |
|
841 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_curr_symbol() const |
|
842 { return _Locale_currency_symbol(_M_monetary); } |
|
843 |
|
844 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_positive_sign() const |
|
845 { return _Locale_positive_sign(_M_monetary); } |
|
846 |
|
847 _STLP_DECLSPEC string moneypunct_byname<char, false>::do_negative_sign() const |
|
848 { return _Locale_negative_sign(_M_monetary); } |
|
849 |
|
850 _STLP_DECLSPEC int moneypunct_byname<char, false>::do_frac_digits() const |
|
851 { return _Locale_frac_digits(_M_monetary); } |
|
852 |
|
853 // |
|
854 // moneypunct_byname<wchar_t> |
|
855 // |
|
856 #if !defined (_STLP_NO_WCHAR_T) |
|
857 |
|
858 _STLP_DECLSPEC moneypunct_byname<wchar_t, true>::moneypunct_byname(const char * name, |
|
859 size_t refs, _Locale_name_hint* hint): |
|
860 moneypunct<wchar_t, true>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) { |
|
861 if (!_M_monetary) |
|
862 locale::_M_throw_runtime_error(); |
|
863 _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary); |
|
864 } |
|
865 |
|
866 _STLP_DECLSPEC moneypunct_byname<wchar_t, true>::~moneypunct_byname() |
|
867 { _STLP_PRIV __release_monetary(_M_monetary); } |
|
868 |
|
869 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, true>::do_decimal_point() const |
|
870 { return _Locale_mon_decimal_point(_M_monetary); } |
|
871 |
|
872 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, true>::do_thousands_sep() const |
|
873 { return _Locale_mon_thousands_sep(_M_monetary); } |
|
874 |
|
875 _STLP_DECLSPEC string moneypunct_byname<wchar_t, true>::do_grouping() const |
|
876 { return _Locale_mon_grouping(_M_monetary); } |
|
877 |
|
878 inline wstring __do_widen (string const& str) { |
|
879 #if defined (_STLP_NO_MEMBER_TEMPLATES) || defined (_STLP_MSVC) || defined(__MRC__) || defined(__SC__) //*ty 05/26/2001 - added workaround for mpw |
|
880 wstring::_Reserve_t __Reserve; |
|
881 size_t __size = str.size(); |
|
882 wstring result(__Reserve, __size); |
|
883 copy(str.begin(), str.end(), result.begin()); |
|
884 #else |
|
885 wstring result(str.begin(), str.end()); |
|
886 #endif |
|
887 return result; |
|
888 } |
|
889 |
|
890 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, true>::do_curr_symbol() const |
|
891 { return __do_widen(_Locale_int_curr_symbol(_M_monetary)); } |
|
892 |
|
893 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, true>::do_positive_sign() const |
|
894 { return __do_widen(_Locale_positive_sign(_M_monetary)); } |
|
895 |
|
896 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, true>::do_negative_sign() const |
|
897 { return __do_widen(_Locale_negative_sign(_M_monetary)); } |
|
898 |
|
899 _STLP_DECLSPEC int moneypunct_byname<wchar_t, true>::do_frac_digits() const |
|
900 { return _Locale_int_frac_digits(_M_monetary); } |
|
901 |
|
902 _STLP_DECLSPEC moneypunct_byname<wchar_t, false>::moneypunct_byname(const char * name, |
|
903 size_t refs, _Locale_name_hint* hint): |
|
904 moneypunct<wchar_t, false>(refs), _M_monetary(_STLP_PRIV __acquire_monetary(name, hint)) { |
|
905 if (!_M_monetary) |
|
906 locale::_M_throw_runtime_error() ; |
|
907 _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary); |
|
908 } |
|
909 |
|
910 _STLP_DECLSPEC moneypunct_byname<wchar_t, false>::~moneypunct_byname() |
|
911 { _STLP_PRIV __release_monetary(_M_monetary); } |
|
912 |
|
913 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, false>::do_decimal_point() const |
|
914 { return _Locale_mon_decimal_point(_M_monetary); } |
|
915 |
|
916 _STLP_DECLSPEC wchar_t moneypunct_byname<wchar_t, false>::do_thousands_sep() const |
|
917 { return _Locale_mon_thousands_sep(_M_monetary); } |
|
918 |
|
919 _STLP_DECLSPEC string moneypunct_byname<wchar_t, false>::do_grouping() const |
|
920 { return _Locale_mon_grouping(_M_monetary); } |
|
921 |
|
922 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, false>::do_curr_symbol() const |
|
923 { return __do_widen(_Locale_currency_symbol(_M_monetary)); } |
|
924 |
|
925 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, false>::do_positive_sign() const |
|
926 { return __do_widen(_Locale_positive_sign(_M_monetary)); } |
|
927 |
|
928 _STLP_DECLSPEC wstring moneypunct_byname<wchar_t, false>::do_negative_sign() const |
|
929 { return __do_widen(_Locale_negative_sign(_M_monetary)); } |
|
930 |
|
931 _STLP_DECLSPEC int moneypunct_byname<wchar_t, false>::do_frac_digits() const |
|
932 { return _Locale_frac_digits(_M_monetary); } |
|
933 |
|
934 #endif |
|
935 |
|
936 _STLP_END_NAMESPACE |
|
937 |
|
938 #include "message_facets.h" |
|
939 |
|
940 _STLP_BEGIN_NAMESPACE |
|
941 |
|
942 _STLP_MOVE_TO_PRIV_NAMESPACE |
|
943 |
|
944 void _Catalog_locale_map::insert(nl_catd_type key, const locale& L) { |
|
945 _STLP_TRY { |
|
946 #if !defined(_STLP_NO_TYPEINFO) && !defined(_STLP_NO_RTTI) |
|
947 // Don't bother to do anything unless we're using a non-default ctype facet |
|
948 # ifdef _STLP_NO_WCHAR_T |
|
949 typedef char _Char; |
|
950 # else |
|
951 typedef wchar_t _Char; |
|
952 # endif |
|
953 |
|
954 typedef ctype<_Char> wctype; |
|
955 wctype const& wct = use_facet<wctype>(L); |
|
956 if (typeid(wct) != typeid(wctype)) { |
|
957 # endif /* _STLP_NO_TYPEINFO */ |
|
958 if (!M) |
|
959 M = new map_type; |
|
960 |
|
961 #if defined (__SC__) |
|
962 if (!M) delete M; |
|
963 #endif |
|
964 M->insert(map_type::value_type(key, L)); |
|
965 #if !defined(_STLP_NO_TYPEINFO) && !defined(_STLP_NO_RTTI) |
|
966 } |
|
967 # endif /* _STLP_NO_TYPEINFO */ |
|
968 } |
|
969 _STLP_CATCH_ALL {} |
|
970 } |
|
971 |
|
972 void _Catalog_locale_map::erase(nl_catd_type key) { |
|
973 if (M) |
|
974 M->erase(key); |
|
975 } |
|
976 |
|
977 locale _Catalog_locale_map::lookup(nl_catd_type key) const { |
|
978 if (M) { |
|
979 map_type::const_iterator i = M->find(key); |
|
980 return i != M->end() ? (*i).second : locale::classic(); |
|
981 } |
|
982 else |
|
983 return locale::classic(); |
|
984 } |
|
985 |
|
986 |
|
987 #if defined (_STLP_USE_NL_CATD_MAPPING) |
|
988 _STLP_VOLATILE __stl_atomic_t _Catalog_nl_catd_map::_count = 0; |
|
989 |
|
990 messages_base::catalog _Catalog_nl_catd_map::insert(nl_catd_type cat) { |
|
991 messages_base::catalog &res = Mr[cat]; |
|
992 if ( res == 0 ) { |
|
993 #if defined (_STLP_ATOMIC_INCREMENT) |
|
994 res = __STATIC_CAST(int, _STLP_ATOMIC_INCREMENT(&_count)); |
|
995 #else |
|
996 static _STLP_STATIC_MUTEX _Count_lock _STLP_MUTEX_INITIALIZER; |
|
997 { |
|
998 _STLP_auto_lock sentry(_Count_lock); |
|
999 res = __STATIC_CAST(int, ++_count); |
|
1000 } |
|
1001 #endif |
|
1002 M[res] = cat; |
|
1003 } |
|
1004 return res; |
|
1005 } |
|
1006 |
|
1007 void _Catalog_nl_catd_map::erase(messages_base::catalog cat) { |
|
1008 map_type::iterator mit(M.find(cat)); |
|
1009 if (mit != M.end()) { |
|
1010 Mr.erase((*mit).second); |
|
1011 M.erase(mit); |
|
1012 } |
|
1013 } |
|
1014 #endif |
|
1015 |
|
1016 //---------------------------------------------------------------------- |
|
1017 // |
|
1018 // |
|
1019 |
|
1020 _Messages_impl::_Messages_impl(bool is_wide, _Locale_name_hint* hint) : |
|
1021 _M_message_obj(0), _M_map(0) { |
|
1022 _M_delete = true; |
|
1023 if (is_wide) |
|
1024 _M_map = new _Catalog_locale_map; |
|
1025 _M_message_obj = __acquire_messages("C", hint); |
|
1026 } |
|
1027 |
|
1028 _Messages_impl::_Messages_impl(bool is_wide, _Locale_messages* msg_obj ) : |
|
1029 _M_message_obj(msg_obj), _M_map(0) { |
|
1030 _M_delete = true; |
|
1031 if (is_wide) |
|
1032 _M_map = new _Catalog_locale_map; |
|
1033 } |
|
1034 |
|
1035 _Messages_impl::~_Messages_impl() { |
|
1036 __release_messages(_M_message_obj); |
|
1037 if (_M_map) delete _M_map; |
|
1038 } |
|
1039 |
|
1040 _Messages::catalog _Messages_impl::do_open(const string& filename, const locale& L) const { |
|
1041 nl_catd_type result = _M_message_obj ? _Locale_catopen(_M_message_obj, filename.c_str()) |
|
1042 : (nl_catd_type)(-1); |
|
1043 |
|
1044 if ( result != (nl_catd_type)(-1) ) { |
|
1045 if ( _M_map != 0 ) { |
|
1046 _M_map->insert(result, L); |
|
1047 } |
|
1048 return _M_cat.insert( result ); |
|
1049 } |
|
1050 |
|
1051 return -1; |
|
1052 } |
|
1053 |
|
1054 string _Messages_impl::do_get(catalog cat, |
|
1055 int set, int p_id, const string& dfault) const { |
|
1056 return _M_message_obj != 0 && cat >= 0 |
|
1057 ? string(_Locale_catgets(_M_message_obj, _M_cat[cat], set, p_id, dfault.c_str())) |
|
1058 : dfault; |
|
1059 } |
|
1060 |
|
1061 #if !defined (_STLP_NO_WCHAR_T) |
|
1062 |
|
1063 wstring |
|
1064 _Messages_impl::do_get(catalog thecat, |
|
1065 int set, int p_id, const wstring& dfault) const { |
|
1066 typedef ctype<wchar_t> wctype; |
|
1067 const wctype& ct = use_facet<wctype>(_M_map->lookup( _M_cat[thecat] ) ); |
|
1068 |
|
1069 const char* str = _Locale_catgets(_M_message_obj, _M_cat[thecat], set, p_id, ""); |
|
1070 |
|
1071 // Verify that the lookup failed; an empty string might represent success. |
|
1072 if (!str) |
|
1073 return dfault; |
|
1074 else if (str[0] == '\0') { |
|
1075 const char* str2 = _Locale_catgets(_M_message_obj, _M_cat[thecat], set, p_id, "*"); |
|
1076 if (!str2 || ((str2[0] == '*') && (str2[1] == '\0'))) |
|
1077 return dfault; |
|
1078 } |
|
1079 |
|
1080 // str is correct. Now we must widen it to get a wstring. |
|
1081 size_t n = strlen(str); |
|
1082 |
|
1083 // NOT PORTABLE. What we're doing relies on internal details of the |
|
1084 // string implementation. (Contiguity of string elements.) |
|
1085 wstring result(n, wchar_t(0)); |
|
1086 ct.widen(str, str + n, &*result.begin()); |
|
1087 return result; |
|
1088 } |
|
1089 |
|
1090 #endif |
|
1091 |
|
1092 void _Messages_impl::do_close(catalog thecat) const { |
|
1093 if (_M_message_obj) |
|
1094 _Locale_catclose(_M_message_obj, _M_cat[thecat]); |
|
1095 if (_M_map) _M_map->erase(_M_cat[thecat]); |
|
1096 _M_cat.erase( thecat ); |
|
1097 } |
|
1098 |
|
1099 _STLP_MOVE_TO_STD_NAMESPACE |
|
1100 |
|
1101 //---------------------------------------------------------------------- |
|
1102 // messages<char> |
|
1103 |
|
1104 _STLP_DECLSPEC messages<char>::messages(size_t refs) : |
|
1105 locale::facet(refs), _M_impl(new _STLP_PRIV _Messages_impl(false)) {} |
|
1106 |
|
1107 _STLP_DECLSPEC messages<char>::messages(size_t refs, _Locale_messages* msg_obj) : locale::facet(refs), |
|
1108 _M_impl(new _STLP_PRIV _Messages_impl(false, msg_obj)) {} |
|
1109 |
|
1110 |
|
1111 //---------------------------------------------------------------------- |
|
1112 // messages_byname<char> |
|
1113 |
|
1114 _STLP_DECLSPEC messages_byname<char>::messages_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
1115 : messages<char>(refs, name ? _STLP_PRIV __acquire_messages(name, hint) : 0) {} |
|
1116 |
|
1117 _STLP_DECLSPEC messages_byname<char>::~messages_byname() {} |
|
1118 |
|
1119 #if !defined (_STLP_NO_WCHAR_T) |
|
1120 |
|
1121 //---------------------------------------------------------------------- |
|
1122 // messages<wchar_t> |
|
1123 |
|
1124 _STLP_DECLSPEC messages<wchar_t>::messages(size_t refs) : |
|
1125 locale::facet(refs), _M_impl(new _STLP_PRIV _Messages_impl(true)) {} |
|
1126 |
|
1127 _STLP_DECLSPEC messages<wchar_t>::messages(size_t refs, _Locale_messages* msg_obj) |
|
1128 : locale::facet(refs), |
|
1129 _M_impl(new _STLP_PRIV _Messages_impl(true, msg_obj)) {} |
|
1130 |
|
1131 //---------------------------------------------------------------------- |
|
1132 // messages_byname<wchar_t> |
|
1133 |
|
1134 |
|
1135 _STLP_DECLSPEC messages_byname<wchar_t>::messages_byname(const char* name, size_t refs, _Locale_name_hint* hint) |
|
1136 : messages<wchar_t>(refs, name ? _STLP_PRIV __acquire_messages(name, hint) : 0) {} |
|
1137 |
|
1138 _STLP_DECLSPEC messages_byname<wchar_t>::~messages_byname() {} |
|
1139 |
|
1140 #endif |
|
1141 |
|
1142 _STLP_END_NAMESPACE |
|
1143 |