home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / src / facets_byname.cpp < prev    next >
C/C++ Source or Header  |  2002-01-18  |  32KB  |  1,168 lines

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