genericopenlibs/cppstdlib/stl/src/locale.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     3  *
       
     4  * Copyright (c) 1999
       
     5  * Silicon Graphics Computer Systems, Inc.
       
     6  *
       
     7  * Copyright (c) 1999
       
     8  * Boris Fomitchev
       
     9  *
       
    10  * This material is provided "as is", with absolutely no warranty expressed
       
    11  * or implied. Any use is at your own risk.
       
    12  *
       
    13  * Permission to use or copy this software for any purpose is hereby granted
       
    14  * without fee, provided the above notices are retained on all copies.
       
    15  * Permission to modify the code and to distribute modified code is granted,
       
    16  * provided the above notices are retained, and a notice that the code was
       
    17  * modified is included with the above copyright notice.
       
    18  *
       
    19  */
       
    20 
       
    21 // This file is #included into locale_impl.cpp, due to locale use many
       
    22 // statics from locale_impl.cpp
       
    23 
       
    24 #if defined(__SYMBIAN32__WSD__)
       
    25 # include "libstdcppwsd.h"
       
    26 
       
    27 void locale_index_lock_init()
       
    28 	{	
       
    29 	get_locale_Index_lock()._M_lock.iState = _ENeedsNormalInit;
       
    30 	get_locale_Index_lock()._M_lock.iPtr = NULL;
       
    31 	get_locale_Index_lock()._M_lock.iReentry = 0;
       
    32 	}
       
    33 # endif
       
    34 
       
    35 _STLP_BEGIN_NAMESPACE
       
    36 
       
    37 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
       
    38 #  define locale _STLP_NO_MEM_T_NAME(loc)
       
    39 #endif
       
    40 
       
    41 _STLP_DECLSPEC locale::facet::~facet() {}
       
    42 
       
    43 #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES)
       
    44 // members that fail to be templates
       
    45 _STLP_DECLSPEC bool locale::operator()(const string& __x,
       
    46                         const string& __y) const
       
    47 { return __locale_do_operator_call(*this, __x, __y); }
       
    48 
       
    49 #  if !defined (_STLP_NO_WCHAR_T)
       
    50 _STLP_DECLSPEC bool locale::operator()(const wstring& __x,
       
    51                         const wstring& __y) const
       
    52 { return __locale_do_operator_call(*this, __x, __y); }
       
    53 #  endif
       
    54 #endif
       
    55 
       
    56 _STLP_DECLSPEC void _STLP_CALL locale::_M_throw_runtime_error(const char* name) {
       
    57   char buf[256];
       
    58 
       
    59   if (name) {
       
    60     const char* prefix = "bad locale name: ";
       
    61 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
       
    62     strcpy(buf, prefix);
       
    63     strncat(buf, name, _STLP_ARRAY_SIZE(buf) - strlen(prefix));
       
    64     buf[_STLP_ARRAY_SIZE(buf) - 1] = 0;
       
    65 #else
       
    66     strcpy_s(_STLP_ARRAY_AND_SIZE(buf), prefix);
       
    67     strncat_s(_STLP_ARRAY_AND_SIZE(buf), name, _TRUNCATE);
       
    68 #endif
       
    69   }
       
    70   else {
       
    71 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
       
    72     strcpy(buf, "locale error");
       
    73 #else
       
    74     strcpy_s(_STLP_ARRAY_AND_SIZE(buf), "locale error");
       
    75 #endif
       
    76   }
       
    77   _STLP_THROW(runtime_error(buf));
       
    78 }
       
    79 
       
    80 
       
    81 // Takes a reference to a locale::id, and returns its numeric index.
       
    82 // If no numeric index has yet been assigned, assigns one.  The return
       
    83 // value is always positive.
       
    84 static size_t _Stl_loc_get_index(locale::id& id) {
       
    85   if (id._M_index == 0) {
       
    86 #if defined (_STLP_ATOMIC_INCREMENT) && \
       
    87    (!defined (_STLP_WIN32_VERSION) || (_STLP_WIN32_VERSION > 0x0400))
       
    88     static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max);
       
    89     id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index);
       
    90 #else
       
    91 #if !defined(__SYMBIAN32__WSD__)
       
    92     static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER;
       
    93 #endif //__SYMBIAN32__WSD__
       
    94     _STLP_auto_lock sentry(_Index_lock);
       
    95     size_t new_index = locale::id::_S_max++;
       
    96     id._M_index = new_index;
       
    97 #endif
       
    98   }
       
    99   return id._M_index;
       
   100 }
       
   101 
       
   102 // Default constructor: create a copy of the global locale.
       
   103 _STLP_DECLSPEC locale::locale() _STLP_NOTHROW
       
   104   : _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl))
       
   105 {}
       
   106 
       
   107 // Copy constructor
       
   108 _STLP_DECLSPEC locale::locale(const locale& L) _STLP_NOTHROW
       
   109   : _M_impl( _get_Locale_impl( L._M_impl ) )
       
   110 {}
       
   111 
       
   112 _STLP_DECLSPEC void locale::_M_insert(facet* f, locale::id& n) {
       
   113   if (f)
       
   114     _M_impl->insert(f, _Stl_loc_get_index(n));
       
   115 }
       
   116 
       
   117 locale::locale( _Locale_impl* impl ) :
       
   118   _M_impl( _get_Locale_impl( impl ) )
       
   119 {}
       
   120 
       
   121 // Create a locale from a name.
       
   122 _STLP_DECLSPEC locale::locale(const char* name)
       
   123   : _M_impl(0) {
       
   124   if (!name)
       
   125     _M_throw_runtime_error(0);
       
   126 
       
   127   if (is_C_locale_name(name)) {
       
   128     _M_impl = _get_Locale_impl( locale::classic()._M_impl );
       
   129     return;
       
   130   }
       
   131 
       
   132   _Locale_impl* impl = 0;
       
   133   _STLP_TRY {
       
   134     impl = new _Locale_impl(locale::id::_S_max, name);
       
   135 
       
   136     // Insert categories one at a time.
       
   137     _Locale_name_hint *hint = 0;
       
   138     hint = impl->insert_ctype_facets(name, hint);
       
   139     hint = impl->insert_numeric_facets(name, hint);
       
   140     hint = impl->insert_time_facets(name, hint);
       
   141     hint = impl->insert_collate_facets(name, hint);
       
   142     hint = impl->insert_monetary_facets(name, hint);
       
   143     impl->insert_messages_facets(name, hint);
       
   144     // reassign impl
       
   145     _M_impl = _get_Locale_impl( impl );
       
   146   }
       
   147   _STLP_UNWIND(delete impl);
       
   148 }
       
   149 
       
   150 // Give L a name where all facets except those in category c
       
   151 // are taken from name1, and those in category c are taken from name2.
       
   152 static void _Stl_loc_combine_names(_Locale_impl* L,
       
   153                                    const char* name1, const char* name2,
       
   154                                    locale::category c) {
       
   155   if ((c & locale::all) == 0 || strcmp(name1, name2) == 0)
       
   156     L->name = name1;
       
   157   else if ((c & locale::all) == locale::all)
       
   158     L->name = name2;
       
   159   else {
       
   160     // Decompose the names.
       
   161     char ctype_buf[_Locale_MAX_SIMPLE_NAME];
       
   162     char numeric_buf[_Locale_MAX_SIMPLE_NAME];
       
   163     char time_buf[_Locale_MAX_SIMPLE_NAME];
       
   164     char collate_buf[_Locale_MAX_SIMPLE_NAME];
       
   165     char monetary_buf[_Locale_MAX_SIMPLE_NAME];
       
   166     char messages_buf[_Locale_MAX_SIMPLE_NAME];
       
   167 
       
   168     // TODO: check returnvalues?
       
   169     _Locale_extract_ctype_name((c & locale::ctype) ? name2 : name1, ctype_buf, 0);
       
   170     _Locale_extract_numeric_name((c & locale::numeric) ? name2 : name1, numeric_buf, 0);
       
   171     _Locale_extract_time_name((c & locale::time) ? name2 : name1, time_buf, 0);
       
   172     _Locale_extract_collate_name((c & locale::collate) ? name2 : name1, collate_buf, 0);
       
   173     _Locale_extract_monetary_name((c & locale::monetary) ? name2 : name1, monetary_buf, 0);
       
   174     _Locale_extract_messages_name((c & locale::messages) ? name2 : name1, messages_buf, 0);
       
   175 
       
   176     // Construct a new composite name.
       
   177     char composite_buf[_Locale_MAX_COMPOSITE_NAME];
       
   178     // TODO: check returnvalue?
       
   179     _Locale_compose_name(composite_buf,
       
   180                          ctype_buf, numeric_buf, time_buf,
       
   181                          collate_buf, monetary_buf, messages_buf,
       
   182                          name1);
       
   183     L->name = composite_buf;
       
   184   }
       
   185 }
       
   186 
       
   187 // Create a locale that's a copy of L, except that all of the facets
       
   188 // in category c are instead constructed by name.
       
   189 _STLP_DECLSPEC locale::locale(const locale& L, const char* name, locale::category c)
       
   190   : _M_impl(0) {
       
   191   if (name == 0 || (_Nameless == name))
       
   192     _M_throw_runtime_error(name);
       
   193 
       
   194   _Locale_impl* impl = 0;
       
   195 
       
   196   _STLP_TRY {
       
   197     impl = new _Locale_impl(*L._M_impl);
       
   198     _Stl_loc_combine_names(impl, L._M_impl->name.c_str(), name, c);
       
   199 
       
   200     _Locale_name_hint *hint = 0;
       
   201     if (c & locale::ctype)
       
   202       hint = impl->insert_ctype_facets(name, hint);
       
   203     if (c & locale::numeric)
       
   204       hint = impl->insert_numeric_facets(name, hint);
       
   205     if (c & locale::time)
       
   206       hint = impl->insert_time_facets(name, hint);
       
   207     if (c & locale::collate)
       
   208       hint = impl->insert_collate_facets(name, hint);
       
   209     if (c & locale::monetary)
       
   210       hint = impl->insert_monetary_facets(name, hint);
       
   211     if (c & locale::messages)
       
   212       impl->insert_messages_facets(name, hint);
       
   213     _M_impl = _get_Locale_impl( impl );
       
   214   }
       
   215   _STLP_UNWIND(delete impl)
       
   216 }
       
   217 #if defined(__SYMBIAN32__WSD__)
       
   218 #define id GetFacetLocaleId()
       
   219 #endif
       
   220 // Contruct a new locale where all facets that aren't in category c
       
   221 // come from L1, and all those that are in category c come from L2.
       
   222 _STLP_DECLSPEC locale::locale(const locale& L1, const locale& L2, category c)
       
   223   : _M_impl(0) {
       
   224   _Locale_impl* impl = new _Locale_impl(*L1._M_impl);
       
   225 
       
   226   _Locale_impl* i2 = L2._M_impl;
       
   227 
       
   228   if (L1.name() != _Nameless && L2.name() != _Nameless)
       
   229     _Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c);
       
   230   else {
       
   231     impl->name = _Nameless;
       
   232   }
       
   233 
       
   234   if (c & collate) {
       
   235     impl->insert( i2, _STLP_STD::collate<char>::id);
       
   236 # ifndef _STLP_NO_WCHAR_T
       
   237     impl->insert( i2, _STLP_STD::collate<wchar_t>::id);
       
   238 # endif
       
   239   }
       
   240   if (c & ctype) {
       
   241     impl->insert( i2, _STLP_STD::ctype<char>::id);
       
   242     impl->insert( i2, _STLP_STD::codecvt<char, char, mbstate_t>::id);
       
   243 # ifndef _STLP_NO_WCHAR_T
       
   244     impl->insert( i2, _STLP_STD::ctype<wchar_t>::id);
       
   245     impl->insert( i2, _STLP_STD::codecvt<wchar_t, char, mbstate_t>::id);
       
   246 # endif
       
   247   }
       
   248   if (c & monetary) {
       
   249     impl->insert( i2, _STLP_STD::moneypunct<char, true>::id);
       
   250     impl->insert( i2, _STLP_STD::moneypunct<char, false>::id);
       
   251     impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
       
   252     impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
       
   253 # ifndef _STLP_NO_WCHAR_T
       
   254     impl->insert( i2, _STLP_STD::moneypunct<wchar_t, true>::id);
       
   255     impl->insert( i2, _STLP_STD::moneypunct<wchar_t, false>::id);
       
   256     impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
       
   257     impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
       
   258 # endif
       
   259   }
       
   260   if (c & numeric) {
       
   261     impl->insert( i2, _STLP_STD::numpunct<char>::id);
       
   262     impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
       
   263     impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
       
   264 # ifndef _STLP_NO_WCHAR_T
       
   265     impl->insert( i2, _STLP_STD::numpunct<wchar_t>::id);
       
   266     impl->insert( i2, num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
       
   267     impl->insert( i2, num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
       
   268 # endif
       
   269   }
       
   270   if (c & time) {
       
   271     impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
       
   272     impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
       
   273 # ifndef _STLP_NO_WCHAR_T
       
   274     impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
       
   275     impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
       
   276 # endif
       
   277   }
       
   278   if (c & messages) {
       
   279     impl->insert( i2, _STLP_STD::messages<char>::id);
       
   280 # ifndef _STLP_NO_WCHAR_T
       
   281     impl->insert( i2, _STLP_STD::messages<wchar_t>::id);
       
   282 # endif    
       
   283   }
       
   284 #if defined(__SYMBIAN32__WSD__)
       
   285 #undef id
       
   286 #endif
       
   287   _M_impl = _get_Locale_impl( impl );
       
   288 }
       
   289 
       
   290 // Destructor.
       
   291 _STLP_DECLSPEC locale::~locale() _STLP_NOTHROW {
       
   292   if (_M_impl)
       
   293     _release_Locale_impl(_M_impl);
       
   294 }
       
   295 
       
   296 // Assignment operator.  Much like the copy constructor: just a bit of
       
   297 // pointer twiddling.
       
   298 _STLP_DECLSPEC const locale& locale::operator=(const locale& L) _STLP_NOTHROW {
       
   299   if (this->_M_impl != L._M_impl) {
       
   300     if (this->_M_impl)
       
   301       _release_Locale_impl(this->_M_impl);
       
   302     this->_M_impl = _get_Locale_impl(L._M_impl);
       
   303   }
       
   304   return *this;
       
   305 }
       
   306 
       
   307 _STLP_DECLSPEC locale::facet* locale::_M_get_facet(const locale::id& n) const {
       
   308   return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0;
       
   309 }
       
   310 
       
   311 _STLP_DECLSPEC locale::facet* locale::_M_use_facet(const locale::id& n) const {
       
   312   locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0);
       
   313   if (!f)
       
   314     _M_impl->_M_throw_bad_cast();
       
   315   return f;
       
   316 }
       
   317 
       
   318 _STLP_DECLSPEC string locale::name() const {
       
   319   return _M_impl->name;
       
   320 }
       
   321 
       
   322 // Compare two locales for equality.
       
   323 _STLP_DECLSPEC bool locale::operator==(const locale& L) const {
       
   324   return this->_M_impl == L._M_impl ||
       
   325          (this->name() == L.name() && this->name() != _Nameless);
       
   326 }
       
   327 
       
   328 _STLP_DECLSPEC bool locale::operator!=(const locale& L) const {
       
   329   return !(*this == L);
       
   330 }
       
   331 
       
   332 // static data members.
       
   333 
       
   334 _STLP_DECLSPEC const locale& _STLP_CALL locale::classic() {
       
   335   return *_Stl_get_classic_locale();
       
   336 }
       
   337 
       
   338 _STLP_DECLSPEC locale _STLP_CALL locale::global(const locale& L) {
       
   339   locale old(_Stl_get_global_locale()->_M_impl);
       
   340   if (_Stl_get_global_locale()->_M_impl != L._M_impl) {
       
   341     _release_Locale_impl(_Stl_get_global_locale()->_M_impl);
       
   342     // this assign should be atomic, should be fixed here:
       
   343     _Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl);
       
   344 
       
   345     // Set the global C locale, if appropriate.
       
   346 #if !defined(_STLP_NO_LOCALE_SUPPORT)
       
   347     if (L.name() != _Nameless)
       
   348       setlocale(LC_ALL, L.name().c_str());
       
   349 #endif
       
   350   }
       
   351 
       
   352   return old;
       
   353 }
       
   354 
       
   355 # if !defined (_STLP_STATIC_CONST_INIT_BUG) && ! defined (_STLP_USE_DECLSPEC)
       
   356 
       
   357 const locale::category locale::none;
       
   358 const locale::category locale::collate;
       
   359 const locale::category locale::ctype;
       
   360 const locale::category locale::monetary;
       
   361 const locale::category locale::numeric;
       
   362 const locale::category locale::time;
       
   363 const locale::category locale::messages;
       
   364 const locale::category locale::all;
       
   365 
       
   366 # endif
       
   367 
       
   368 _STLP_END_NAMESPACE
       
   369