1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/src/locale.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,369 @@
1.4 +/*
1.5 + * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
1.6 + *
1.7 + * Copyright (c) 1999
1.8 + * Silicon Graphics Computer Systems, Inc.
1.9 + *
1.10 + * Copyright (c) 1999
1.11 + * Boris Fomitchev
1.12 + *
1.13 + * This material is provided "as is", with absolutely no warranty expressed
1.14 + * or implied. Any use is at your own risk.
1.15 + *
1.16 + * Permission to use or copy this software for any purpose is hereby granted
1.17 + * without fee, provided the above notices are retained on all copies.
1.18 + * Permission to modify the code and to distribute modified code is granted,
1.19 + * provided the above notices are retained, and a notice that the code was
1.20 + * modified is included with the above copyright notice.
1.21 + *
1.22 + */
1.23 +
1.24 +// This file is #included into locale_impl.cpp, due to locale use many
1.25 +// statics from locale_impl.cpp
1.26 +
1.27 +#if defined(__SYMBIAN32__WSD__)
1.28 +# include "libstdcppwsd.h"
1.29 +
1.30 +void locale_index_lock_init()
1.31 + {
1.32 + get_locale_Index_lock()._M_lock.iState = _ENeedsNormalInit;
1.33 + get_locale_Index_lock()._M_lock.iPtr = NULL;
1.34 + get_locale_Index_lock()._M_lock.iReentry = 0;
1.35 + }
1.36 +# endif
1.37 +
1.38 +_STLP_BEGIN_NAMESPACE
1.39 +
1.40 +#if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
1.41 +# define locale _STLP_NO_MEM_T_NAME(loc)
1.42 +#endif
1.43 +
1.44 +_STLP_DECLSPEC locale::facet::~facet() {}
1.45 +
1.46 +#if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES)
1.47 +// members that fail to be templates
1.48 +_STLP_DECLSPEC bool locale::operator()(const string& __x,
1.49 + const string& __y) const
1.50 +{ return __locale_do_operator_call(*this, __x, __y); }
1.51 +
1.52 +# if !defined (_STLP_NO_WCHAR_T)
1.53 +_STLP_DECLSPEC bool locale::operator()(const wstring& __x,
1.54 + const wstring& __y) const
1.55 +{ return __locale_do_operator_call(*this, __x, __y); }
1.56 +# endif
1.57 +#endif
1.58 +
1.59 +_STLP_DECLSPEC void _STLP_CALL locale::_M_throw_runtime_error(const char* name) {
1.60 + char buf[256];
1.61 +
1.62 + if (name) {
1.63 + const char* prefix = "bad locale name: ";
1.64 +#if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
1.65 + strcpy(buf, prefix);
1.66 + strncat(buf, name, _STLP_ARRAY_SIZE(buf) - strlen(prefix));
1.67 + buf[_STLP_ARRAY_SIZE(buf) - 1] = 0;
1.68 +#else
1.69 + strcpy_s(_STLP_ARRAY_AND_SIZE(buf), prefix);
1.70 + strncat_s(_STLP_ARRAY_AND_SIZE(buf), name, _TRUNCATE);
1.71 +#endif
1.72 + }
1.73 + else {
1.74 +#if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
1.75 + strcpy(buf, "locale error");
1.76 +#else
1.77 + strcpy_s(_STLP_ARRAY_AND_SIZE(buf), "locale error");
1.78 +#endif
1.79 + }
1.80 + _STLP_THROW(runtime_error(buf));
1.81 +}
1.82 +
1.83 +
1.84 +// Takes a reference to a locale::id, and returns its numeric index.
1.85 +// If no numeric index has yet been assigned, assigns one. The return
1.86 +// value is always positive.
1.87 +static size_t _Stl_loc_get_index(locale::id& id) {
1.88 + if (id._M_index == 0) {
1.89 +#if defined (_STLP_ATOMIC_INCREMENT) && \
1.90 + (!defined (_STLP_WIN32_VERSION) || (_STLP_WIN32_VERSION > 0x0400))
1.91 + static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max);
1.92 + id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index);
1.93 +#else
1.94 +#if !defined(__SYMBIAN32__WSD__)
1.95 + static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER;
1.96 +#endif //__SYMBIAN32__WSD__
1.97 + _STLP_auto_lock sentry(_Index_lock);
1.98 + size_t new_index = locale::id::_S_max++;
1.99 + id._M_index = new_index;
1.100 +#endif
1.101 + }
1.102 + return id._M_index;
1.103 +}
1.104 +
1.105 +// Default constructor: create a copy of the global locale.
1.106 +_STLP_DECLSPEC locale::locale() _STLP_NOTHROW
1.107 + : _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl))
1.108 +{}
1.109 +
1.110 +// Copy constructor
1.111 +_STLP_DECLSPEC locale::locale(const locale& L) _STLP_NOTHROW
1.112 + : _M_impl( _get_Locale_impl( L._M_impl ) )
1.113 +{}
1.114 +
1.115 +_STLP_DECLSPEC void locale::_M_insert(facet* f, locale::id& n) {
1.116 + if (f)
1.117 + _M_impl->insert(f, _Stl_loc_get_index(n));
1.118 +}
1.119 +
1.120 +locale::locale( _Locale_impl* impl ) :
1.121 + _M_impl( _get_Locale_impl( impl ) )
1.122 +{}
1.123 +
1.124 +// Create a locale from a name.
1.125 +_STLP_DECLSPEC locale::locale(const char* name)
1.126 + : _M_impl(0) {
1.127 + if (!name)
1.128 + _M_throw_runtime_error(0);
1.129 +
1.130 + if (is_C_locale_name(name)) {
1.131 + _M_impl = _get_Locale_impl( locale::classic()._M_impl );
1.132 + return;
1.133 + }
1.134 +
1.135 + _Locale_impl* impl = 0;
1.136 + _STLP_TRY {
1.137 + impl = new _Locale_impl(locale::id::_S_max, name);
1.138 +
1.139 + // Insert categories one at a time.
1.140 + _Locale_name_hint *hint = 0;
1.141 + hint = impl->insert_ctype_facets(name, hint);
1.142 + hint = impl->insert_numeric_facets(name, hint);
1.143 + hint = impl->insert_time_facets(name, hint);
1.144 + hint = impl->insert_collate_facets(name, hint);
1.145 + hint = impl->insert_monetary_facets(name, hint);
1.146 + impl->insert_messages_facets(name, hint);
1.147 + // reassign impl
1.148 + _M_impl = _get_Locale_impl( impl );
1.149 + }
1.150 + _STLP_UNWIND(delete impl);
1.151 +}
1.152 +
1.153 +// Give L a name where all facets except those in category c
1.154 +// are taken from name1, and those in category c are taken from name2.
1.155 +static void _Stl_loc_combine_names(_Locale_impl* L,
1.156 + const char* name1, const char* name2,
1.157 + locale::category c) {
1.158 + if ((c & locale::all) == 0 || strcmp(name1, name2) == 0)
1.159 + L->name = name1;
1.160 + else if ((c & locale::all) == locale::all)
1.161 + L->name = name2;
1.162 + else {
1.163 + // Decompose the names.
1.164 + char ctype_buf[_Locale_MAX_SIMPLE_NAME];
1.165 + char numeric_buf[_Locale_MAX_SIMPLE_NAME];
1.166 + char time_buf[_Locale_MAX_SIMPLE_NAME];
1.167 + char collate_buf[_Locale_MAX_SIMPLE_NAME];
1.168 + char monetary_buf[_Locale_MAX_SIMPLE_NAME];
1.169 + char messages_buf[_Locale_MAX_SIMPLE_NAME];
1.170 +
1.171 + // TODO: check returnvalues?
1.172 + _Locale_extract_ctype_name((c & locale::ctype) ? name2 : name1, ctype_buf, 0);
1.173 + _Locale_extract_numeric_name((c & locale::numeric) ? name2 : name1, numeric_buf, 0);
1.174 + _Locale_extract_time_name((c & locale::time) ? name2 : name1, time_buf, 0);
1.175 + _Locale_extract_collate_name((c & locale::collate) ? name2 : name1, collate_buf, 0);
1.176 + _Locale_extract_monetary_name((c & locale::monetary) ? name2 : name1, monetary_buf, 0);
1.177 + _Locale_extract_messages_name((c & locale::messages) ? name2 : name1, messages_buf, 0);
1.178 +
1.179 + // Construct a new composite name.
1.180 + char composite_buf[_Locale_MAX_COMPOSITE_NAME];
1.181 + // TODO: check returnvalue?
1.182 + _Locale_compose_name(composite_buf,
1.183 + ctype_buf, numeric_buf, time_buf,
1.184 + collate_buf, monetary_buf, messages_buf,
1.185 + name1);
1.186 + L->name = composite_buf;
1.187 + }
1.188 +}
1.189 +
1.190 +// Create a locale that's a copy of L, except that all of the facets
1.191 +// in category c are instead constructed by name.
1.192 +_STLP_DECLSPEC locale::locale(const locale& L, const char* name, locale::category c)
1.193 + : _M_impl(0) {
1.194 + if (name == 0 || (_Nameless == name))
1.195 + _M_throw_runtime_error(name);
1.196 +
1.197 + _Locale_impl* impl = 0;
1.198 +
1.199 + _STLP_TRY {
1.200 + impl = new _Locale_impl(*L._M_impl);
1.201 + _Stl_loc_combine_names(impl, L._M_impl->name.c_str(), name, c);
1.202 +
1.203 + _Locale_name_hint *hint = 0;
1.204 + if (c & locale::ctype)
1.205 + hint = impl->insert_ctype_facets(name, hint);
1.206 + if (c & locale::numeric)
1.207 + hint = impl->insert_numeric_facets(name, hint);
1.208 + if (c & locale::time)
1.209 + hint = impl->insert_time_facets(name, hint);
1.210 + if (c & locale::collate)
1.211 + hint = impl->insert_collate_facets(name, hint);
1.212 + if (c & locale::monetary)
1.213 + hint = impl->insert_monetary_facets(name, hint);
1.214 + if (c & locale::messages)
1.215 + impl->insert_messages_facets(name, hint);
1.216 + _M_impl = _get_Locale_impl( impl );
1.217 + }
1.218 + _STLP_UNWIND(delete impl)
1.219 +}
1.220 +#if defined(__SYMBIAN32__WSD__)
1.221 +#define id GetFacetLocaleId()
1.222 +#endif
1.223 +// Contruct a new locale where all facets that aren't in category c
1.224 +// come from L1, and all those that are in category c come from L2.
1.225 +_STLP_DECLSPEC locale::locale(const locale& L1, const locale& L2, category c)
1.226 + : _M_impl(0) {
1.227 + _Locale_impl* impl = new _Locale_impl(*L1._M_impl);
1.228 +
1.229 + _Locale_impl* i2 = L2._M_impl;
1.230 +
1.231 + if (L1.name() != _Nameless && L2.name() != _Nameless)
1.232 + _Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c);
1.233 + else {
1.234 + impl->name = _Nameless;
1.235 + }
1.236 +
1.237 + if (c & collate) {
1.238 + impl->insert( i2, _STLP_STD::collate<char>::id);
1.239 +# ifndef _STLP_NO_WCHAR_T
1.240 + impl->insert( i2, _STLP_STD::collate<wchar_t>::id);
1.241 +# endif
1.242 + }
1.243 + if (c & ctype) {
1.244 + impl->insert( i2, _STLP_STD::ctype<char>::id);
1.245 + impl->insert( i2, _STLP_STD::codecvt<char, char, mbstate_t>::id);
1.246 +# ifndef _STLP_NO_WCHAR_T
1.247 + impl->insert( i2, _STLP_STD::ctype<wchar_t>::id);
1.248 + impl->insert( i2, _STLP_STD::codecvt<wchar_t, char, mbstate_t>::id);
1.249 +# endif
1.250 + }
1.251 + if (c & monetary) {
1.252 + impl->insert( i2, _STLP_STD::moneypunct<char, true>::id);
1.253 + impl->insert( i2, _STLP_STD::moneypunct<char, false>::id);
1.254 + impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
1.255 + impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
1.256 +# ifndef _STLP_NO_WCHAR_T
1.257 + impl->insert( i2, _STLP_STD::moneypunct<wchar_t, true>::id);
1.258 + impl->insert( i2, _STLP_STD::moneypunct<wchar_t, false>::id);
1.259 + impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
1.260 + impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
1.261 +# endif
1.262 + }
1.263 + if (c & numeric) {
1.264 + impl->insert( i2, _STLP_STD::numpunct<char>::id);
1.265 + impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
1.266 + impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
1.267 +# ifndef _STLP_NO_WCHAR_T
1.268 + impl->insert( i2, _STLP_STD::numpunct<wchar_t>::id);
1.269 + impl->insert( i2, num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
1.270 + impl->insert( i2, num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
1.271 +# endif
1.272 + }
1.273 + if (c & time) {
1.274 + impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
1.275 + impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
1.276 +# ifndef _STLP_NO_WCHAR_T
1.277 + impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
1.278 + impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
1.279 +# endif
1.280 + }
1.281 + if (c & messages) {
1.282 + impl->insert( i2, _STLP_STD::messages<char>::id);
1.283 +# ifndef _STLP_NO_WCHAR_T
1.284 + impl->insert( i2, _STLP_STD::messages<wchar_t>::id);
1.285 +# endif
1.286 + }
1.287 +#if defined(__SYMBIAN32__WSD__)
1.288 +#undef id
1.289 +#endif
1.290 + _M_impl = _get_Locale_impl( impl );
1.291 +}
1.292 +
1.293 +// Destructor.
1.294 +_STLP_DECLSPEC locale::~locale() _STLP_NOTHROW {
1.295 + if (_M_impl)
1.296 + _release_Locale_impl(_M_impl);
1.297 +}
1.298 +
1.299 +// Assignment operator. Much like the copy constructor: just a bit of
1.300 +// pointer twiddling.
1.301 +_STLP_DECLSPEC const locale& locale::operator=(const locale& L) _STLP_NOTHROW {
1.302 + if (this->_M_impl != L._M_impl) {
1.303 + if (this->_M_impl)
1.304 + _release_Locale_impl(this->_M_impl);
1.305 + this->_M_impl = _get_Locale_impl(L._M_impl);
1.306 + }
1.307 + return *this;
1.308 +}
1.309 +
1.310 +_STLP_DECLSPEC locale::facet* locale::_M_get_facet(const locale::id& n) const {
1.311 + return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0;
1.312 +}
1.313 +
1.314 +_STLP_DECLSPEC locale::facet* locale::_M_use_facet(const locale::id& n) const {
1.315 + locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0);
1.316 + if (!f)
1.317 + _M_impl->_M_throw_bad_cast();
1.318 + return f;
1.319 +}
1.320 +
1.321 +_STLP_DECLSPEC string locale::name() const {
1.322 + return _M_impl->name;
1.323 +}
1.324 +
1.325 +// Compare two locales for equality.
1.326 +_STLP_DECLSPEC bool locale::operator==(const locale& L) const {
1.327 + return this->_M_impl == L._M_impl ||
1.328 + (this->name() == L.name() && this->name() != _Nameless);
1.329 +}
1.330 +
1.331 +_STLP_DECLSPEC bool locale::operator!=(const locale& L) const {
1.332 + return !(*this == L);
1.333 +}
1.334 +
1.335 +// static data members.
1.336 +
1.337 +_STLP_DECLSPEC const locale& _STLP_CALL locale::classic() {
1.338 + return *_Stl_get_classic_locale();
1.339 +}
1.340 +
1.341 +_STLP_DECLSPEC locale _STLP_CALL locale::global(const locale& L) {
1.342 + locale old(_Stl_get_global_locale()->_M_impl);
1.343 + if (_Stl_get_global_locale()->_M_impl != L._M_impl) {
1.344 + _release_Locale_impl(_Stl_get_global_locale()->_M_impl);
1.345 + // this assign should be atomic, should be fixed here:
1.346 + _Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl);
1.347 +
1.348 + // Set the global C locale, if appropriate.
1.349 +#if !defined(_STLP_NO_LOCALE_SUPPORT)
1.350 + if (L.name() != _Nameless)
1.351 + setlocale(LC_ALL, L.name().c_str());
1.352 +#endif
1.353 + }
1.354 +
1.355 + return old;
1.356 +}
1.357 +
1.358 +# if !defined (_STLP_STATIC_CONST_INIT_BUG) && ! defined (_STLP_USE_DECLSPEC)
1.359 +
1.360 +const locale::category locale::none;
1.361 +const locale::category locale::collate;
1.362 +const locale::category locale::ctype;
1.363 +const locale::category locale::monetary;
1.364 +const locale::category locale::numeric;
1.365 +const locale::category locale::time;
1.366 +const locale::category locale::messages;
1.367 +const locale::category locale::all;
1.368 +
1.369 +# endif
1.370 +
1.371 +_STLP_END_NAMESPACE
1.372 +