Bug Summary

File:stlport/unxlngi6.pro/misc/build/STLport-4.5/src/facets_byname.cpp
Location:line 72, column 26
Description:Array access (from variable 'p') results in a null pointer dereference

Annotated Source Code

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