os/ossrv/genericopenlibs/cppstdlib/stl/src/locale.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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