home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stl453up.zip / stl453fx / src / locale_impl.cpp < prev    next >
C/C++ Source or Header  |  2002-04-29  |  16KB  |  476 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 "locale_impl.h"
  21. #include <locale>
  22. #include <typeinfo>
  23. #include <stdexcept>
  24. #include "c_locale.h"
  25. #include "aligned_buffer.h"
  26.  
  27.  
  28. #include "locale_impl.h"
  29. #include <stl/_codecvt.h>
  30. #include <stl/_collate.h>
  31. #include <stl/_ctype.h>
  32. #include <stl/_monetary.h>
  33. #include "message_facets.h"
  34.  
  35. _STLP_BEGIN_NAMESPACE
  36.  
  37. _Locale_impl::_Locale_impl(const char* s) : name(s) {}
  38. _Locale_impl::~_Locale_impl() {}
  39. void _Locale_impl::incr() {}
  40. void _Locale_impl::decr() {}
  41.  
  42. // _Locale_impl non-inline member functions.
  43. void _STLP_CALL
  44. _Locale_impl::_M_throw_bad_cast()
  45. {
  46.   _STLP_THROW(bad_cast());  
  47. }
  48.  
  49. static void 
  50. _Stl_loc_assign_ids() {
  51.   // This assigns ids to every facet that is a member of a category,
  52.   // and also to money_get/put, num_get/put, and time_get/put
  53.   // instantiated using ordinary pointers as the input/output
  54.   // iterators.  (The default is [io]streambuf_iterator.)
  55.  
  56.   money_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index                     = 8;
  57.   money_get<char, const char*>::id._M_index        = 9;
  58.   money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index                     = 10;
  59.   money_put<char, char*>::id._M_index              = 11;
  60.  
  61.   num_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index                       = 12;
  62.   num_get<char, const char*>::id._M_index          = 13;
  63.   num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index                       = 14;
  64.   num_put<char, char*>::id._M_index                = 15;
  65.   time_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index                      = 16;
  66.   time_get<char, const char*>::id._M_index         = 17;
  67.   time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index                      = 18;
  68.   time_put<char, char*>::id._M_index               = 19;
  69.  
  70. # ifndef _STLP_NO_WCHAR_T
  71.  
  72.   money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index                  = 27;
  73.   money_get<wchar_t, const wchar_t*>::id._M_index  = 28;
  74.   money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index                  = 29;
  75.   money_put<wchar_t, wchar_t*>::id._M_index        = 30;
  76.  
  77.   num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index                       = 31;
  78.   num_get<wchar_t, const wchar_t*>::id._M_index    = 32;
  79.   num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::id._M_index                      = 33;
  80.   num_put<wchar_t, wchar_t*>::id._M_index          = 34;
  81.   time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index                   = 35;
  82.   time_get<wchar_t, const wchar_t*>::id._M_index   = 36;
  83.   time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index                   = 37;
  84.   time_put<wchar_t, wchar_t*>::id._M_index         = 38;
  85.   //  messages<wchar_t>::id._M_index                   = 38;
  86. # endif
  87.  
  88.   //  locale::id::_S_max                               = 39;
  89. }
  90.  
  91. static _Stl_aligned_buffer<_Locale_impl> _S_classic_locale;
  92.  
  93. static _Stl_aligned_buffer<collate<char> > _S_collate_char;
  94. static _Stl_aligned_buffer<ctype<char> > _S_ctype_char;
  95.  
  96. # ifndef _STLP_NO_MBSTATE_T
  97. static _Stl_aligned_buffer<codecvt<char, char, mbstate_t> > _S_codecvt_char;
  98. # endif
  99.  
  100. static _Stl_aligned_buffer<moneypunct<char, true> > _S_moneypunct_true_char;
  101. static _Stl_aligned_buffer<moneypunct<char, false> > _S_moneypunct_false_char;
  102. static _Stl_aligned_buffer<numpunct<char> > _S_numpunct_char;
  103. static _Stl_aligned_buffer<messages<char> > _S_messages_char;
  104.  
  105. static _Stl_aligned_buffer<money_get<char, istreambuf_iterator<char, char_traits<char> > > > _S_money_get_char;
  106. static _Stl_aligned_buffer<money_put<char, ostreambuf_iterator<char, char_traits<char> > > > _S_money_put_char;
  107. static _Stl_aligned_buffer<num_get<char, istreambuf_iterator<char, char_traits<char> > > > _S_num_get_char;
  108. static _Stl_aligned_buffer<num_put<char, ostreambuf_iterator<char, char_traits<char> > > > _S_num_put_char;
  109. static _Stl_aligned_buffer<time_get<char, istreambuf_iterator<char, char_traits<char> > > > _S_time_get_char;
  110. static _Stl_aligned_buffer<time_put<char, ostreambuf_iterator<char, char_traits<char> > > > _S_time_put_char;
  111.  
  112. # ifndef _STLP_NO_WCHAR_T
  113. static _Stl_aligned_buffer<collate<wchar_t> > _S_collate_wchar;
  114. static _Stl_aligned_buffer<ctype<wchar_t> > _S_ctype_wchar;
  115. # ifndef _STLP_NO_MBSTATE_T
  116. static _Stl_aligned_buffer<codecvt<wchar_t, char, mbstate_t> > _S_codecvt_wchar;
  117. # endif
  118. static _Stl_aligned_buffer<moneypunct<wchar_t, true> > _S_moneypunct_true_wchar;
  119. static _Stl_aligned_buffer<moneypunct<wchar_t, false> > _S_moneypunct_false_wchar;
  120. static _Stl_aligned_buffer<numpunct<wchar_t> > _S_numpunct_wchar;
  121. static _Stl_aligned_buffer<messages<wchar_t> > _S_messages_wchar;
  122.  
  123. static _Stl_aligned_buffer<money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > > _S_money_get_wchar;
  124. static _Stl_aligned_buffer<money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > > _S_money_put_wchar;
  125. static _Stl_aligned_buffer<num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > > _S_num_get_wchar;
  126. static _Stl_aligned_buffer<num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > > _S_num_put_wchar;
  127. static _Stl_aligned_buffer<time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > > _S_time_get_wchar;
  128. static _Stl_aligned_buffer<time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > > _S_time_put_wchar;
  129.  
  130. # endif
  131.  
  132. static _Messages _Null_messages;
  133.  
  134. static locale::facet* _S_classic_facets[] = {
  135.   (locale::facet*)0,
  136.   (locale::facet*)&_S_collate_char,
  137.   (locale::facet*)&_S_ctype_char, 
  138. # ifndef _STLP_NO_MBSTATE_T
  139.     (locale::facet*)&_S_codecvt_char,
  140. # else
  141.     (locale::facet*)0, 
  142. # endif
  143.   (locale::facet*)&_S_moneypunct_true_char,
  144.   (locale::facet*)&_S_moneypunct_false_char,
  145.   (locale::facet*)&_S_numpunct_char,
  146.   (locale::facet*)&_S_messages_char,
  147.  
  148.   (locale::facet*)&_S_money_get_char,
  149.   (locale::facet*)0,
  150.   (locale::facet*)&_S_money_put_char,
  151.   (locale::facet*)0,
  152.  
  153.   (locale::facet*)&_S_num_get_char,
  154.   (locale::facet*)0,
  155.   (locale::facet*)&_S_num_put_char,
  156.   (locale::facet*)0,
  157.   (locale::facet*)&_S_time_get_char,
  158.   (locale::facet*)0,
  159.   (locale::facet*)&_S_time_put_char,
  160.   (locale::facet*)0,
  161. # ifndef _STLP_NO_WCHAR_T
  162.   (locale::facet*)&_S_collate_wchar,
  163.   (locale::facet*)&_S_ctype_wchar, 
  164.  
  165. # ifndef _STLP_NO_MBSTATE_T
  166.   (locale::facet*)&_S_codecvt_wchar,
  167. # else
  168. (locale::facet*)0
  169. # endif
  170.   (locale::facet*)&_S_moneypunct_true_wchar,
  171.   (locale::facet*)&_S_moneypunct_false_wchar,
  172.   (locale::facet*)&_S_numpunct_wchar,
  173.   (locale::facet*)&_S_messages_wchar,
  174.  
  175.   (locale::facet*)&_S_money_get_wchar,
  176.   (locale::facet*)0,
  177.   (locale::facet*)&_S_money_put_wchar,
  178.   (locale::facet*)0,
  179.  
  180.   (locale::facet*)&_S_num_get_wchar,
  181.   (locale::facet*)0,
  182.   (locale::facet*)&_S_num_put_wchar,
  183.   (locale::facet*)0,
  184.   (locale::facet*)&_S_time_get_wchar,
  185.   (locale::facet*)0,
  186.   (locale::facet*)&_S_time_put_wchar,
  187.   (locale::facet*)0,
  188. # endif
  189.   0
  190. };
  191.  
  192. _Locale_impl* 
  193. _Locale_impl::make_classic_locale() {
  194.   // The classic locale contains every facet that belongs to a category.
  195.   _Locale_impl* classic = (_Locale_impl*) &_S_classic_locale;
  196.   
  197.   new (classic) _Locale_impl("C");
  198.  
  199.   classic->facets = _S_classic_facets;
  200.   classic->_M_size = locale::id::_S_max;
  201.  
  202.   // ctype category
  203.   new(&_S_ctype_char) ctype<char>(0, false, 1);
  204.   // collate category
  205.   new(&_S_collate_char) collate<char>(1);
  206.   new(&_S_codecvt_char) codecvt<char, char, mbstate_t>(1);
  207.   // numeric category
  208.   new(&_S_numpunct_char) numpunct<char>(1);
  209.   new (&_S_num_get_char) num_get<char, istreambuf_iterator<char, char_traits<char> > >(1);
  210.   new (&_S_num_put_char) num_put<char, ostreambuf_iterator<char, char_traits<char> > >(1);
  211.   new (&_S_time_get_char) time_get<char, istreambuf_iterator<char, char_traits<char> > >(1);
  212.   new (&_S_time_put_char) time_put<char, ostreambuf_iterator<char, char_traits<char> > >(1);
  213.   // monetary category
  214.   new (&_S_moneypunct_true_char) moneypunct<char, true>(1);
  215.   new (&_S_moneypunct_false_char) moneypunct<char, false>(1);
  216.   new (&_S_money_get_char) money_get<char, istreambuf_iterator<char, char_traits<char> > >(1);
  217.   new (&_S_money_put_char) money_put<char, ostreambuf_iterator<char, char_traits<char> > >(1);
  218.   // messages category
  219.   new (&_S_messages_char)messages<char>(&_Null_messages);
  220.  
  221. # ifndef _STLP_NO_WCHAR_T
  222.   // ctype category
  223.   new(&_S_ctype_wchar) ctype<wchar_t>(1);
  224.   // collate category
  225.   new(&_S_collate_wchar) collate<wchar_t>(1);
  226.   new(&_S_codecvt_wchar) codecvt<wchar_t, char, mbstate_t>(1);
  227.   // numeric category
  228.   new(&_S_numpunct_wchar) numpunct<wchar_t>(1);
  229.   new (&_S_num_get_wchar) num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1);
  230.   new (&_S_num_put_wchar) num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1);
  231.   new (&_S_time_get_wchar) time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1);
  232.   new (&_S_time_put_wchar) time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1);
  233.   new (&_S_messages_wchar)messages<wchar_t>(&_Null_messages);
  234.   // monetary category
  235.   new (&_S_moneypunct_true_wchar) moneypunct<wchar_t, true>(1);
  236.   new (&_S_moneypunct_false_wchar) moneypunct<wchar_t, false>(1);
  237.   new (&_S_money_get_wchar) money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1);
  238.   new (&_S_money_put_wchar) money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1);
  239. # endif
  240.  
  241.   return classic;
  242. }
  243.  
  244.  
  245. //----------------------------------------------------------------------
  246.  
  247. // Declarations of (non-template) facets' static data members
  248. size_t locale::id::_S_max = 39;
  249.  
  250. _STLP_STATIC_MEMBER_DECLSPEC locale::id collate<char>::id = { 1 };
  251. _STLP_STATIC_MEMBER_DECLSPEC locale::id ctype<char>::id = { 2 };
  252.  
  253. # ifndef _STLP_NO_MBSTATE_T
  254. _STLP_STATIC_MEMBER_DECLSPEC locale::id codecvt<char, char, mbstate_t>::id = { 3 };
  255. #  ifndef _STLP_NO_WCHAR_T
  256. _STLP_STATIC_MEMBER_DECLSPEC locale::id codecvt<wchar_t, char, mbstate_t>::id = { 22 };
  257. #  endif
  258. # endif
  259.  
  260. _STLP_STATIC_MEMBER_DECLSPEC locale::id moneypunct<char, true>::id = { 4 };
  261. _STLP_STATIC_MEMBER_DECLSPEC locale::id moneypunct<char, false>::id = { 5 };
  262. _STLP_STATIC_MEMBER_DECLSPEC locale::id numpunct<char>::id = { 6 } ;
  263. _STLP_STATIC_MEMBER_DECLSPEC locale::id messages<char>::id = { 7 };
  264.  
  265. # ifndef _STLP_NO_WCHAR_T
  266. _STLP_STATIC_MEMBER_DECLSPEC locale::id collate<wchar_t>::id = { 20 };
  267. _STLP_STATIC_MEMBER_DECLSPEC locale::id ctype<wchar_t>::id = { 21 };
  268.  
  269. _STLP_STATIC_MEMBER_DECLSPEC locale::id moneypunct<wchar_t, true>::id = { 23 } ;
  270. _STLP_STATIC_MEMBER_DECLSPEC locale::id moneypunct<wchar_t, false>::id = { 24 } ;
  271.  
  272. _STLP_STATIC_MEMBER_DECLSPEC locale::id numpunct<wchar_t>::id = { 25 };
  273. _STLP_STATIC_MEMBER_DECLSPEC locale::id messages<wchar_t>::id = { 26 };
  274. # endif
  275.  
  276. //
  277. // locale class
  278. //
  279.  
  280. locale::facet::~facet() {}
  281.  
  282. # if ! defined ( _STLP_MEMBER_TEMPLATES ) || defined (_STLP_INLINE_MEMBER_TEMPLATES)
  283. // members that fail to be templates 
  284. bool locale::operator()(const string& __x,
  285.                         const string& __y) const {
  286.   return __locale_do_operator_call(this, __x, __y);
  287. }
  288.  
  289. #  ifndef _STLP_NO_WCHAR_T
  290. bool locale::operator()(const wstring& __x,
  291.                   const wstring& __y) const {
  292.   return __locale_do_operator_call(this, __x, __y);
  293. }
  294. #  endif
  295. # endif
  296.  
  297.  
  298. _Locale_impl*   _Stl_loc_global_impl    = 0;
  299. locale          _Stl_loc_classic_locale((_Locale_impl*) &_S_classic_locale);
  300. _STLP_STATIC_MUTEX _Stl_loc_global_locale_lock _STLP_MUTEX_INITIALIZER;
  301.  
  302.   
  303. //----------------------------------------------------------------------
  304. // class locale
  305.  
  306. void _STLP_CALL
  307. locale::_M_throw_runtime_error(const char* name)
  308. {
  309.   char buf[256];
  310.  
  311.   if (name) {
  312.     const char* prefix = "bad locale name: ";
  313.     strcpy(buf, prefix);
  314.     strncat(buf, name, 256 - strlen(prefix));
  315.     buf[255] = '\0';
  316.   }
  317.   else {
  318.     strcpy(buf, "locale error");
  319.   }
  320.   _STLP_THROW(runtime_error(buf));
  321. }
  322.  
  323. #if !( defined (__BORLANDC__) && defined(_RTLDLL))
  324.  
  325. long ios_base::_Loc_init::_S_count = 0;
  326.  
  327. //TORLAB DEBUG original ios_base::_Loc_init::_Loc_init() {
  328. _Export ios_base::_Loc_init::_Loc_init() { //TORLAB DEBUG added _Export keyword
  329.   if (_S_count++ == 0)
  330.       locale::_S_initialize();
  331. }
  332.  
  333. ios_base::_Loc_init::~_Loc_init() {
  334.     if (--_S_count == 0)
  335.       locale::_S_uninitialize();
  336. }
  337.  
  338. #endif /* _RTLDLL */
  339.  
  340. // Initialization of the locale system.  This must be called before
  341. // any locales are constructed.  (Meaning that it must be called when
  342. // the I/O library itself is initialized.)
  343. void _STLP_CALL
  344. locale::_S_initialize()
  345. {
  346.   _Stl_loc_assign_ids();
  347.   _Stl_loc_global_impl = _Locale_impl::make_classic_locale();
  348. }
  349.  
  350.  
  351.  
  352. void _STLP_CALL
  353. locale::_S_uninitialize()
  354. {
  355.   _Stl_loc_global_impl->decr();
  356. }
  357.  
  358.  
  359. // Default constructor: create a copy of the global locale.
  360. locale::locale() : _M_impl(0) {
  361.   _M_impl = _S_copy_impl(_Stl_loc_global_impl);
  362. }
  363.  
  364. locale::locale(_Locale_impl* impl) : _M_impl(impl)
  365. {}
  366.  
  367. // Copy constructor
  368. locale::locale(const locale& L) _STLP_NOTHROW
  369.   : _M_impl(0)
  370. {
  371.   _M_impl = _S_copy_impl(L._M_impl);
  372. }
  373.  
  374. // Destructor.
  375. locale::~locale() _STLP_NOTHROW
  376. {
  377.   _M_impl->decr();
  378. }
  379.  
  380. // Assignment operator.  Much like the copy constructor: just a bit of
  381. // pointer twiddling.
  382. const locale& locale::operator=(const locale& L) _STLP_NOTHROW
  383. {
  384.   if (this->_M_impl != L._M_impl) {
  385.     this->_M_impl->decr();
  386.     this->_M_impl = _S_copy_impl(L._M_impl);
  387.   }
  388.   return *this;
  389. }
  390.  
  391. locale::facet* locale::_M_get_facet(const locale::id& n) const
  392. {
  393.   return n._M_index < _M_impl->size()
  394.     ? (locale::facet*)_M_impl->facets[n._M_index]
  395.     : (locale::facet*) 0;
  396. }
  397.  
  398. locale::facet* locale::_M_use_facet(const locale::id& n) const
  399. {
  400.   locale::facet* f = (n._M_index < _M_impl->size()
  401.     ? (locale::facet*)_M_impl->facets[n._M_index]
  402.     : (locale::facet*) 0);
  403.   if (!f)
  404.     _M_impl->_M_throw_bad_cast();
  405.   return f;
  406. }
  407.  
  408. string locale::name() const {
  409.   return _M_impl->name;
  410. }
  411.  
  412. static string _Nameless("*");
  413.  
  414. // Compare two locales for equality.
  415. bool locale::operator==(const locale& L) const {
  416.  
  417.   return this->_M_impl == L._M_impl ||
  418.          (this->name() == L.name() && this->name() != _Nameless);
  419. }
  420.  
  421. bool locale::operator!=(const locale& L) const {
  422.   return !(*this == L);
  423. }
  424.  
  425. // Static member functions.
  426. const locale&  _STLP_CALL
  427. locale::classic() {
  428.   return _Stl_loc_classic_locale;
  429. }
  430.  
  431. locale  _STLP_CALL
  432. locale::global(const locale& L) 
  433. {
  434.   locale old;                   // A copy of the old global locale.
  435.  
  436.   L._M_impl->incr();
  437.   {
  438.     _STLP_auto_lock lock(_Stl_loc_global_locale_lock);
  439.     _Stl_loc_global_impl->decr();     // We made a copy, so it can't be zero.
  440.     _Stl_loc_global_impl = L._M_impl;
  441.   }
  442.  
  443.                                 // Set the global C locale, if appropriate.
  444. #if !defined(_STLP_WINCE)
  445.   if (L.name() != _Nameless)
  446.     setlocale(LC_ALL, L.name().c_str());
  447. #endif
  448.  
  449.   return old;
  450. }
  451.  
  452.  
  453. // static data members.
  454.  
  455. # if !defined (_STLP_STATIC_CONST_INIT_BUG) && ! defined (_STLP_USE_DECLSPEC)
  456.  
  457. const locale::category locale::none;
  458. const locale::category locale::collate;
  459. const locale::category locale::ctype;
  460. const locale::category locale::monetary;
  461. const locale::category locale::numeric;
  462. const locale::category locale::time; 
  463. const locale::category locale::messages;
  464. const locale::category locale::all;
  465.  
  466. # endif
  467.  
  468. _STLP_END_NAMESPACE
  469.  
  470. //
  471. // Facets included in classic locale :
  472. //
  473.  
  474.  
  475.  
  476.