Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlocale.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 00019 #include "stlport_prefix.h" 00020 00021 #include <locale> 00022 #include <stdexcept> 00023 00024 #include "c_locale.h" 00025 #include "locale_impl.h" 00026 00027 _STLP_BEGIN_NAMESPACE 00028 00029 static const string _Nameless("*"); 00030 00031 static inline bool is_C_locale_name (const char* name) 00032 { return ((name[0] == 'C') && (name[1] == 0)); } 00033 00034 locale* _Stl_get_classic_locale(); 00035 locale* _Stl_get_global_locale(); 00036 00037 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) || \ 00038 defined (_STLP_SIGNAL_RUNTIME_COMPATIBILITY) || defined (_STLP_CHECK_RUNTIME_COMPATIBILITY) 00039 # define locale _STLP_NO_MEM_T_NAME(loc) 00040 #endif 00041 00042 locale::facet::~facet() {} 00043 00044 #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES) 00045 // members that fail to be templates 00046 bool locale::operator()(const string& __x, 00047 const string& __y) const 00048 { return __locale_do_operator_call(*this, __x, __y); } 00049 00050 # if !defined (_STLP_NO_WCHAR_T) 00051 bool locale::operator()(const wstring& __x, 00052 const wstring& __y) const 00053 { return __locale_do_operator_call(*this, __x, __y); } 00054 # endif 00055 #endif 00056 00057 void _STLP_CALL locale::_M_throw_on_null_name() 00058 { _STLP_THROW(runtime_error("Invalid null locale name")); } 00059 00060 void _STLP_CALL locale::_M_throw_on_combine_error(const string& name) { 00061 string what = "Unable to find facet"; 00062 what += " in "; 00063 what += name.empty() ? "system" : name.c_str(); 00064 what += " locale"; 00065 _STLP_THROW(runtime_error(what.c_str())); 00066 } 00067 00068 void _STLP_CALL locale::_M_throw_on_creation_failure(int __err_code, 00069 const char* name, const char* facet) { 00070 string what; 00071 switch (__err_code) { 00072 case _STLP_LOC_UNSUPPORTED_FACET_CATEGORY: 00073 what = "No platform localization support for "; 00074 what += facet; 00075 what += " facet category, unable to create facet for "; 00076 what += name[0] == 0 ? "system" : name; 00077 what += " locale"; 00078 break; 00079 case _STLP_LOC_NO_PLATFORM_SUPPORT: 00080 what = "No platform localization support, unable to create "; 00081 what += name[0] == 0 ? "system" : name; 00082 what += " locale"; 00083 break; 00084 default: 00085 case _STLP_LOC_UNKNOWN_NAME: 00086 what = "Unable to create facet "; 00087 what += facet; 00088 what += " from name '"; 00089 what += name; 00090 what += "'"; 00091 break; 00092 case _STLP_LOC_NO_MEMORY: 00093 _STLP_THROW_BAD_ALLOC; 00094 break; 00095 } 00096 00097 _STLP_THROW(runtime_error(what.c_str())); 00098 } 00099 00100 // Takes a reference to a locale::id, assign a numeric index if not already 00101 // affected and returns it. The returned index is always positive. 00102 static const locale::id& _Stl_loc_get_index(locale::id& id) { 00103 if (id._M_index == 0) { 00104 #if defined (_STLP_ATOMIC_INCREMENT) && !defined (_STLP_WIN95_LIKE) 00105 static _STLP_VOLATILE __stl_atomic_t _S_index = __STATIC_CAST(__stl_atomic_t, locale::id::_S_max); 00106 id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index); 00107 #else 00108 static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER; 00109 _STLP_auto_lock sentry(_Index_lock); 00110 size_t new_index = locale::id::_S_max++; 00111 id._M_index = new_index; 00112 #endif 00113 } 00114 return id; 00115 } 00116 00117 // Default constructor: create a copy of the global locale. 00118 locale::locale() _STLP_NOTHROW 00119 : _M_impl(_get_Locale_impl(_Stl_get_global_locale()->_M_impl)) 00120 {} 00121 00122 // Copy constructor 00123 locale::locale(const locale& L) _STLP_NOTHROW 00124 : _M_impl( _get_Locale_impl( L._M_impl ) ) 00125 {} 00126 00127 void locale::_M_insert(facet* f, locale::id& n) { 00128 if (f) 00129 _M_impl->insert(f, _Stl_loc_get_index(n)); 00130 } 00131 00132 locale::locale( _Locale_impl* impl ) : 00133 _M_impl( _get_Locale_impl( impl ) ) 00134 {} 00135 00136 // Create a locale from a name. 00137 locale::locale(const char* name) 00138 : _M_impl(0) { 00139 if (!name) 00140 _M_throw_on_null_name(); 00141 00142 if (is_C_locale_name(name)) { 00143 _M_impl = _get_Locale_impl( locale::classic()._M_impl ); 00144 return; 00145 } 00146 00147 _Locale_impl* impl = 0; 00148 _STLP_TRY { 00149 impl = new _Locale_impl(locale::id::_S_max, name); 00150 00151 // Insert categories one at a time. 00152 _Locale_name_hint *hint = 0; 00153 const char* ctype_name = name; 00154 char ctype_buf[_Locale_MAX_SIMPLE_NAME]; 00155 const char* numeric_name = name; 00156 char numeric_buf[_Locale_MAX_SIMPLE_NAME]; 00157 const char* time_name = name; 00158 char time_buf[_Locale_MAX_SIMPLE_NAME]; 00159 const char* collate_name = name; 00160 char collate_buf[_Locale_MAX_SIMPLE_NAME]; 00161 const char* monetary_name = name; 00162 char monetary_buf[_Locale_MAX_SIMPLE_NAME]; 00163 const char* messages_name = name; 00164 char messages_buf[_Locale_MAX_SIMPLE_NAME]; 00165 hint = impl->insert_ctype_facets(ctype_name, ctype_buf, hint); 00166 hint = impl->insert_numeric_facets(numeric_name, numeric_buf, hint); 00167 hint = impl->insert_time_facets(time_name, time_buf, hint); 00168 hint = impl->insert_collate_facets(collate_name, collate_buf, hint); 00169 hint = impl->insert_monetary_facets(monetary_name, monetary_buf, hint); 00170 impl->insert_messages_facets(messages_name, messages_buf, hint); 00171 00172 // Try to use a normalize locale name in order to have the == operator 00173 // to behave correctly: 00174 if (strcmp(ctype_name, numeric_name) == 0 && 00175 strcmp(ctype_name, time_name) == 0 && 00176 strcmp(ctype_name, collate_name) == 0 && 00177 strcmp(ctype_name, monetary_name) == 0 && 00178 strcmp(ctype_name, messages_name) == 0) { 00179 impl->name = ctype_name; 00180 } 00181 // else we keep current name. 00182 00183 // reassign impl 00184 _M_impl = _get_Locale_impl( impl ); 00185 } 00186 _STLP_UNWIND(delete impl); 00187 } 00188 00189 static void _Stl_loc_combine_names_aux(_Locale_impl* L, 00190 const char* name, 00191 const char* ctype_name, const char* time_name, const char* numeric_name, 00192 const char* collate_name, const char* monetary_name, const char* messages_name, 00193 locale::category c) { 00194 // This function is only called when names has been validated so using _Locale_extract_*_name 00195 // can't fail. 00196 int __err_code; 00197 char buf[_Locale_MAX_SIMPLE_NAME]; 00198 L->name = string("LC_CTYPE=") + _Locale_extract_ctype_name((c & locale::ctype) ? ctype_name : name, buf, 0, &__err_code) + ";"; 00199 L->name += string("LC_TIME=") + _Locale_extract_time_name((c & locale::time) ? time_name : name, buf, 0, &__err_code) + ";"; 00200 L->name += string("LC_NUMERIC=") + _Locale_extract_numeric_name((c & locale::numeric) ? numeric_name : name, buf, 0, &__err_code) + ";"; 00201 L->name += string("LC_COLLATE=") + _Locale_extract_collate_name((c & locale::collate) ? collate_name : name, buf, 0, &__err_code) + ";"; 00202 L->name += string("LC_MONETARY=") + _Locale_extract_monetary_name((c & locale::monetary) ? monetary_name : name, buf, 0, &__err_code) + ";"; 00203 L->name += string("LC_MESSAGES=") + _Locale_extract_messages_name((c & locale::messages) ? messages_name : name, buf, 0, &__err_code); 00204 } 00205 00206 // Give L a name where all facets except those in category c 00207 // are taken from name1, and those in category c are taken from name2. 00208 static void _Stl_loc_combine_names(_Locale_impl* L, 00209 const char* name1, const char* name2, 00210 locale::category c) { 00211 if ((c & locale::all) == 0 || strcmp(name1, name2) == 0) 00212 L->name = name1; 00213 else if ((c & locale::all) == locale::all) 00214 L->name = name2; 00215 else { 00216 _Stl_loc_combine_names_aux(L, name1, name2, name2, name2, name2, name2, name2, c); 00217 } 00218 } 00219 00220 static void _Stl_loc_combine_names(_Locale_impl* L, 00221 const char* name, 00222 const char* ctype_name, const char* time_name, const char* numeric_name, 00223 const char* collate_name, const char* monetary_name, const char* messages_name, 00224 locale::category c) { 00225 if ((c & locale::all) == 0 || (strcmp(name, ctype_name) == 0 && 00226 strcmp(name, time_name) == 0 && 00227 strcmp(name, numeric_name) == 0 && 00228 strcmp(name, collate_name) == 0 && 00229 strcmp(name, monetary_name) == 0 && 00230 strcmp(name, messages_name) == 0)) 00231 L->name = name; 00232 else if ((c & locale::all) == locale::all && strcmp(ctype_name, time_name) == 0 && 00233 strcmp(ctype_name, numeric_name) == 0 && 00234 strcmp(ctype_name, collate_name) == 0 && 00235 strcmp(ctype_name, monetary_name) == 0 && 00236 strcmp(ctype_name, messages_name) == 0) 00237 L->name = ctype_name; 00238 else { 00239 _Stl_loc_combine_names_aux(L, name, ctype_name, time_name, numeric_name, collate_name, monetary_name, messages_name, c); 00240 } 00241 } 00242 00243 00244 // Create a locale that's a copy of L, except that all of the facets 00245 // in category c are instead constructed by name. 00246 locale::locale(const locale& L, const char* name, locale::category c) 00247 : _M_impl(0) { 00248 if (!name) 00249 _M_throw_on_null_name(); 00250 00251 if (_Nameless == name) 00252 _STLP_THROW(runtime_error((string("Invalid locale name '") + _Nameless + "'").c_str())); 00253 00254 _Locale_impl* impl = 0; 00255 00256 _STLP_TRY { 00257 impl = new _Locale_impl(*L._M_impl); 00258 00259 _Locale_name_hint *hint = 0; 00260 const char* ctype_name = name; 00261 char ctype_buf[_Locale_MAX_SIMPLE_NAME]; 00262 const char* numeric_name = name; 00263 char numeric_buf[_Locale_MAX_SIMPLE_NAME]; 00264 const char* time_name = name; 00265 char time_buf[_Locale_MAX_SIMPLE_NAME]; 00266 const char* collate_name = name; 00267 char collate_buf[_Locale_MAX_SIMPLE_NAME]; 00268 const char* monetary_name = name; 00269 char monetary_buf[_Locale_MAX_SIMPLE_NAME]; 00270 const char* messages_name = name; 00271 char messages_buf[_Locale_MAX_SIMPLE_NAME]; 00272 if (c & locale::ctype) 00273 hint = impl->insert_ctype_facets(ctype_name, ctype_buf, hint); 00274 if (c & locale::numeric) 00275 hint = impl->insert_numeric_facets(numeric_name, numeric_buf, hint); 00276 if (c & locale::time) 00277 hint = impl->insert_time_facets(time_name, time_buf, hint); 00278 if (c & locale::collate) 00279 hint = impl->insert_collate_facets(collate_name, collate_buf, hint); 00280 if (c & locale::monetary) 00281 hint = impl->insert_monetary_facets(monetary_name, monetary_buf,hint); 00282 if (c & locale::messages) 00283 impl->insert_messages_facets(messages_name, messages_buf, hint); 00284 00285 _Stl_loc_combine_names(impl, L._M_impl->name.c_str(), 00286 ctype_name, time_name, numeric_name, 00287 collate_name, monetary_name, messages_name, c); 00288 _M_impl = _get_Locale_impl( impl ); 00289 } 00290 _STLP_UNWIND(delete impl) 00291 } 00292 00293 // Contruct a new locale where all facets that aren't in category c 00294 // come from L1, and all those that are in category c come from L2. 00295 locale::locale(const locale& L1, const locale& L2, category c) 00296 : _M_impl(0) { 00297 _Locale_impl* impl = new _Locale_impl(*L1._M_impl); 00298 00299 _Locale_impl* i2 = L2._M_impl; 00300 00301 if (L1.name() != _Nameless && L2.name() != _Nameless) 00302 _Stl_loc_combine_names(impl, L1._M_impl->name.c_str(), L2._M_impl->name.c_str(), c); 00303 else { 00304 impl->name = _Nameless; 00305 } 00306 00307 if (c & collate) { 00308 impl->insert( i2, _STLP_STD::collate<char>::id); 00309 # ifndef _STLP_NO_WCHAR_T 00310 impl->insert( i2, _STLP_STD::collate<wchar_t>::id); 00311 # endif 00312 } 00313 if (c & ctype) { 00314 impl->insert( i2, _STLP_STD::ctype<char>::id); 00315 impl->insert( i2, _STLP_STD::codecvt<char, char, mbstate_t>::id); 00316 # ifndef _STLP_NO_WCHAR_T 00317 impl->insert( i2, _STLP_STD::ctype<wchar_t>::id); 00318 impl->insert( i2, _STLP_STD::codecvt<wchar_t, char, mbstate_t>::id); 00319 # endif 00320 } 00321 if (c & monetary) { 00322 impl->insert( i2, _STLP_STD::moneypunct<char, true>::id); 00323 impl->insert( i2, _STLP_STD::moneypunct<char, false>::id); 00324 impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 00325 impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 00326 # ifndef _STLP_NO_WCHAR_T 00327 impl->insert( i2, _STLP_STD::moneypunct<wchar_t, true>::id); 00328 impl->insert( i2, _STLP_STD::moneypunct<wchar_t, false>::id); 00329 impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00330 impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00331 # endif 00332 } 00333 if (c & numeric) { 00334 impl->insert( i2, _STLP_STD::numpunct<char>::id); 00335 impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 00336 impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 00337 # ifndef _STLP_NO_WCHAR_T 00338 impl->insert( i2, _STLP_STD::numpunct<wchar_t>::id); 00339 impl->insert( i2, _STLP_STD::num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00340 impl->insert( i2, _STLP_STD::num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00341 # endif 00342 } 00343 if (c & time) { 00344 impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id); 00345 impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id); 00346 # ifndef _STLP_NO_WCHAR_T 00347 impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00348 impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id); 00349 # endif 00350 } 00351 if (c & messages) { 00352 impl->insert( i2, _STLP_STD::messages<char>::id); 00353 # ifndef _STLP_NO_WCHAR_T 00354 impl->insert( i2, _STLP_STD::messages<wchar_t>::id); 00355 # endif 00356 } 00357 _M_impl = _get_Locale_impl( impl ); 00358 } 00359 00360 // Destructor. 00361 locale::~locale() _STLP_NOTHROW { 00362 if (_M_impl) 00363 _release_Locale_impl(_M_impl); 00364 } 00365 00366 // Assignment operator. Much like the copy constructor: just a bit of 00367 // pointer twiddling. 00368 const locale& locale::operator=(const locale& L) _STLP_NOTHROW { 00369 if (this->_M_impl != L._M_impl) { 00370 if (this->_M_impl) 00371 _release_Locale_impl(this->_M_impl); 00372 this->_M_impl = _get_Locale_impl(L._M_impl); 00373 } 00374 return *this; 00375 } 00376 00377 locale::facet* locale::_M_get_facet(const locale::id& n) const { 00378 return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0; 00379 } 00380 00381 locale::facet* locale::_M_use_facet(const locale::id& n) const { 00382 locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0); 00383 if (!f) 00384 _M_impl->_M_throw_bad_cast(); 00385 return f; 00386 } 00387 00388 string locale::name() const { 00389 return _M_impl->name; 00390 } 00391 00392 // Compare two locales for equality. 00393 bool locale::operator==(const locale& L) const { 00394 return this->_M_impl == L._M_impl || 00395 (this->name() == L.name() && this->name() != _Nameless); 00396 } 00397 00398 bool locale::operator!=(const locale& L) const { 00399 return !(*this == L); 00400 } 00401 00402 // static data members. 00403 00404 const locale& _STLP_CALL locale::classic() { 00405 return *_Stl_get_classic_locale(); 00406 } 00407 00408 #if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00409 locale _STLP_CALL locale::global(const locale& L) { 00410 #else 00411 _Locale_impl* _STLP_CALL locale::global(const locale& L) { 00412 #endif 00413 locale old(_Stl_get_global_locale()->_M_impl); 00414 if (_Stl_get_global_locale()->_M_impl != L._M_impl) { 00415 _release_Locale_impl(_Stl_get_global_locale()->_M_impl); 00416 // this assign should be atomic, should be fixed here: 00417 _Stl_get_global_locale()->_M_impl = _get_Locale_impl(L._M_impl); 00418 00419 // Set the global C locale, if appropriate. 00420 #if !defined(_STLP_NO_LOCALE_SUPPORT) 00421 if (L.name() != _Nameless) 00422 setlocale(LC_ALL, L.name().c_str()); 00423 #endif 00424 } 00425 00426 #if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00427 return old; 00428 #else 00429 return old._M_impl; 00430 #endif 00431 } 00432 00433 #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION) 00434 const locale::category locale::none; 00435 const locale::category locale::collate; 00436 const locale::category locale::ctype; 00437 const locale::category locale::monetary; 00438 const locale::category locale::numeric; 00439 const locale::category locale::time; 00440 const locale::category locale::messages; 00441 const locale::category locale::all; 00442 #endif 00443 00444 _STLP_END_NAMESPACE 00445 Generated on Sun May 27 2012 04:35:12 for ReactOS by
1.7.6.1
|