ReactOS  0.4.14-dev-337-gf981a68
locale.cpp
Go to the documentation of this file.
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 
19 #include "stlport_prefix.h"
20 
21 #include <locale>
22 #include <stdexcept>
23 
24 #include "c_locale.h"
25 #include "locale_impl.h"
26 
28 
29 static const string _Nameless("*");
30 
31 static inline bool is_C_locale_name (const char* name)
32 { return ((name[0] == 'C') && (name[1] == 0)); }
33 
36 
37 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) || \
38  defined (_STLP_SIGNAL_RUNTIME_COMPATIBILITY) || defined (_STLP_CHECK_RUNTIME_COMPATIBILITY)
39 # define locale _STLP_NO_MEM_T_NAME(loc)
40 #endif
41 
43 
44 #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES)
45 // members that fail to be templates
46 bool locale::operator()(const string& __x,
47  const string& __y) const
48 { return __locale_do_operator_call(*this, __x, __y); }
49 
50 # if !defined (_STLP_NO_WCHAR_T)
51 bool locale::operator()(const wstring& __x,
52  const wstring& __y) const
53 { return __locale_do_operator_call(*this, __x, __y); }
54 # endif
55 #endif
56 
58 { _STLP_THROW(runtime_error("Invalid null locale name")); }
59 
61  string what = "Unable to find facet";
62  what += " in ";
63  what += name.empty() ? "system" : name.c_str();
64  what += " locale";
65  _STLP_THROW(runtime_error(what.c_str()));
66 }
67 
69  const char* name, const char* facet) {
70  string what;
71  switch (__err_code) {
73  what = "No platform localization support for ";
74  what += facet;
75  what += " facet category, unable to create facet for ";
76  what += name[0] == 0 ? "system" : name;
77  what += " locale";
78  break;
80  what = "No platform localization support, unable to create ";
81  what += name[0] == 0 ? "system" : name;
82  what += " locale";
83  break;
84  default:
86  what = "Unable to create facet ";
87  what += facet;
88  what += " from name '";
89  what += name;
90  what += "'";
91  break;
94  break;
95  }
96 
97  _STLP_THROW(runtime_error(what.c_str()));
98 }
99 
100 // Takes a reference to a locale::id, assign a numeric index if not already
101 // affected and returns it. The returned index is always positive.
103  if (id._M_index == 0) {
104 #if defined (_STLP_ATOMIC_INCREMENT) && !defined (_STLP_WIN95_LIKE)
106  id._M_index = _STLP_ATOMIC_INCREMENT(&_S_index);
107 #else
108  static _STLP_STATIC_MUTEX _Index_lock _STLP_MUTEX_INITIALIZER;
109  _STLP_auto_lock sentry(_Index_lock);
110  size_t new_index = locale::id::_S_max++;
111  id._M_index = new_index;
112 #endif
113  }
114  return id;
115 }
116 
117 // Default constructor: create a copy of the global locale.
120 {}
121 
122 // Copy constructor
124  : _M_impl( _get_Locale_impl( L._M_impl ) )
125 {}
126 
128  if (f)
130 }
131 
133  _M_impl( _get_Locale_impl( impl ) )
134 {}
135 
136 // Create a locale from a name.
137 locale::locale(const char* name)
138  : _M_impl(0) {
139  if (!name)
141 
142  if (is_C_locale_name(name)) {
144  return;
145  }
146 
147  _Locale_impl* impl = 0;
148  _STLP_TRY {
149  impl = new _Locale_impl(locale::id::_S_max, name);
150 
151  // Insert categories one at a time.
152  _Locale_name_hint *hint = 0;
153  const char* ctype_name = name;
154  char ctype_buf[_Locale_MAX_SIMPLE_NAME];
155  const char* numeric_name = name;
156  char numeric_buf[_Locale_MAX_SIMPLE_NAME];
157  const char* time_name = name;
158  char time_buf[_Locale_MAX_SIMPLE_NAME];
159  const char* collate_name = name;
160  char collate_buf[_Locale_MAX_SIMPLE_NAME];
161  const char* monetary_name = name;
162  char monetary_buf[_Locale_MAX_SIMPLE_NAME];
163  const char* messages_name = name;
164  char messages_buf[_Locale_MAX_SIMPLE_NAME];
165  hint = impl->insert_ctype_facets(ctype_name, ctype_buf, hint);
166  hint = impl->insert_numeric_facets(numeric_name, numeric_buf, hint);
167  hint = impl->insert_time_facets(time_name, time_buf, hint);
168  hint = impl->insert_collate_facets(collate_name, collate_buf, hint);
169  hint = impl->insert_monetary_facets(monetary_name, monetary_buf, hint);
170  impl->insert_messages_facets(messages_name, messages_buf, hint);
171 
172  // Try to use a normalize locale name in order to have the == operator
173  // to behave correctly:
174  if (strcmp(ctype_name, numeric_name) == 0 &&
175  strcmp(ctype_name, time_name) == 0 &&
176  strcmp(ctype_name, collate_name) == 0 &&
177  strcmp(ctype_name, monetary_name) == 0 &&
178  strcmp(ctype_name, messages_name) == 0) {
179  impl->name = ctype_name;
180  }
181  // else we keep current name.
182 
183  // reassign impl
184  _M_impl = _get_Locale_impl( impl );
185  }
186  _STLP_UNWIND(delete impl);
187 }
188 
190  const char* name,
191  const char* ctype_name, const char* time_name, const char* numeric_name,
192  const char* collate_name, const char* monetary_name, const char* messages_name,
194  // This function is only called when names has been validated so using _Locale_extract_*_name
195  // can't fail.
196  int __err_code;
198  L->name = string("LC_CTYPE=") + _Locale_extract_ctype_name((c & locale::ctype) ? ctype_name : name, buf, 0, &__err_code) + ";";
199  L->name += string("LC_TIME=") + _Locale_extract_time_name((c & locale::time) ? time_name : name, buf, 0, &__err_code) + ";";
200  L->name += string("LC_NUMERIC=") + _Locale_extract_numeric_name((c & locale::numeric) ? numeric_name : name, buf, 0, &__err_code) + ";";
201  L->name += string("LC_COLLATE=") + _Locale_extract_collate_name((c & locale::collate) ? collate_name : name, buf, 0, &__err_code) + ";";
202  L->name += string("LC_MONETARY=") + _Locale_extract_monetary_name((c & locale::monetary) ? monetary_name : name, buf, 0, &__err_code) + ";";
203  L->name += string("LC_MESSAGES=") + _Locale_extract_messages_name((c & locale::messages) ? messages_name : name, buf, 0, &__err_code);
204 }
205 
206 // Give L a name where all facets except those in category c
207 // are taken from name1, and those in category c are taken from name2.
209  const char* name1, const char* name2,
211  if ((c & locale::all) == 0 || strcmp(name1, name2) == 0)
212  L->name = name1;
213  else if ((c & locale::all) == locale::all)
214  L->name = name2;
215  else {
217  }
218 }
219 
221  const char* name,
222  const char* ctype_name, const char* time_name, const char* numeric_name,
223  const char* collate_name, const char* monetary_name, const char* messages_name,
225  if ((c & locale::all) == 0 || (strcmp(name, ctype_name) == 0 &&
226  strcmp(name, time_name) == 0 &&
227  strcmp(name, numeric_name) == 0 &&
228  strcmp(name, collate_name) == 0 &&
229  strcmp(name, monetary_name) == 0 &&
230  strcmp(name, messages_name) == 0))
231  L->name = name;
232  else if ((c & locale::all) == locale::all && strcmp(ctype_name, time_name) == 0 &&
233  strcmp(ctype_name, numeric_name) == 0 &&
234  strcmp(ctype_name, collate_name) == 0 &&
235  strcmp(ctype_name, monetary_name) == 0 &&
236  strcmp(ctype_name, messages_name) == 0)
237  L->name = ctype_name;
238  else {
239  _Stl_loc_combine_names_aux(L, name, ctype_name, time_name, numeric_name, collate_name, monetary_name, messages_name, c);
240  }
241 }
242 
243 
244 // Create a locale that's a copy of L, except that all of the facets
245 // in category c are instead constructed by name.
246 locale::locale(const locale& L, const char* name, locale::category c)
247  : _M_impl(0) {
248  if (!name)
249  _M_throw_on_null_name();
250 
251  if (_Nameless == name)
252  _STLP_THROW(runtime_error((string("Invalid locale name '") + _Nameless + "'").c_str()));
253 
254  _Locale_impl* impl = 0;
255 
256  _STLP_TRY {
257  impl = new _Locale_impl(*L._M_impl);
258 
259  _Locale_name_hint *hint = 0;
260  const char* ctype_name = name;
261  char ctype_buf[_Locale_MAX_SIMPLE_NAME];
262  const char* numeric_name = name;
263  char numeric_buf[_Locale_MAX_SIMPLE_NAME];
264  const char* time_name = name;
265  char time_buf[_Locale_MAX_SIMPLE_NAME];
266  const char* collate_name = name;
267  char collate_buf[_Locale_MAX_SIMPLE_NAME];
268  const char* monetary_name = name;
269  char monetary_buf[_Locale_MAX_SIMPLE_NAME];
270  const char* messages_name = name;
271  char messages_buf[_Locale_MAX_SIMPLE_NAME];
272  if (c & locale::ctype)
273  hint = impl->insert_ctype_facets(ctype_name, ctype_buf, hint);
274  if (c & locale::numeric)
275  hint = impl->insert_numeric_facets(numeric_name, numeric_buf, hint);
276  if (c & locale::time)
277  hint = impl->insert_time_facets(time_name, time_buf, hint);
278  if (c & locale::collate)
279  hint = impl->insert_collate_facets(collate_name, collate_buf, hint);
280  if (c & locale::monetary)
281  hint = impl->insert_monetary_facets(monetary_name, monetary_buf,hint);
282  if (c & locale::messages)
283  impl->insert_messages_facets(messages_name, messages_buf, hint);
284 
285  _Stl_loc_combine_names(impl, L._M_impl->name.c_str(),
286  ctype_name, time_name, numeric_name,
287  collate_name, monetary_name, messages_name, c);
288  _M_impl = _get_Locale_impl( impl );
289  }
290  _STLP_UNWIND(delete impl)
291 }
292 
293 // Contruct a new locale where all facets that aren't in category c
294 // come from L1, and all those that are in category c come from L2.
295 locale::locale(const locale& L1, const locale& L2, category c)
296  : _M_impl(0) {
297  _Locale_impl* impl = new _Locale_impl(*L1._M_impl);
298 
299  _Locale_impl* i2 = L2._M_impl;
300 
301  if (L1.name() != _Nameless && L2.name() != _Nameless)
303  else {
304  impl->name = _Nameless;
305  }
306 
307  if (c & collate) {
309 # ifndef _STLP_NO_WCHAR_T
311 # endif
312  }
313  if (c & ctype) {
316 # ifndef _STLP_NO_WCHAR_T
319 # endif
320  }
321  if (c & monetary) {
324  impl->insert( i2, _STLP_STD::money_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
325  impl->insert( i2, _STLP_STD::money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
326 # ifndef _STLP_NO_WCHAR_T
329  impl->insert( i2, _STLP_STD::money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
330  impl->insert( i2, _STLP_STD::money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
331 # endif
332  }
333  if (c & numeric) {
335  impl->insert( i2, _STLP_STD::num_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
336  impl->insert( i2, _STLP_STD::num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
337 # ifndef _STLP_NO_WCHAR_T
339  impl->insert( i2, _STLP_STD::num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
340  impl->insert( i2, _STLP_STD::num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
341 # endif
342  }
343  if (c & time) {
344  impl->insert( i2, _STLP_STD::time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
345  impl->insert( i2, _STLP_STD::time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
346 # ifndef _STLP_NO_WCHAR_T
347  impl->insert( i2, _STLP_STD::time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
348  impl->insert( i2, _STLP_STD::time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
349 # endif
350  }
351  if (c & messages) {
353 # ifndef _STLP_NO_WCHAR_T
355 # endif
356  }
357  _M_impl = _get_Locale_impl( impl );
358 }
359 
360 // Destructor.
362  if (_M_impl)
364 }
365 
366 // Assignment operator. Much like the copy constructor: just a bit of
367 // pointer twiddling.
369  if (this->_M_impl != L._M_impl) {
370  if (this->_M_impl)
371  _release_Locale_impl(this->_M_impl);
372  this->_M_impl = _get_Locale_impl(L._M_impl);
373  }
374  return *this;
375 }
376 
378  return n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0;
379 }
380 
382  locale::facet* f = (n._M_index < _M_impl->size() ? _M_impl->facets_vec[n._M_index] : 0);
383  if (!f)
385  return f;
386 }
387 
388 string locale::name() const {
389  return _M_impl->name;
390 }
391 
392 // Compare two locales for equality.
393 bool locale::operator==(const locale& L) const {
394  return this->_M_impl == L._M_impl ||
395  (this->name() == L.name() && this->name() != _Nameless);
396 }
397 
398 bool locale::operator!=(const locale& L) const {
399  return !(*this == L);
400 }
401 
402 // static data members.
403 
405  return *_Stl_get_classic_locale();
406 }
407 
408 #if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
410 #else
412 #endif
414  if (_Stl_get_global_locale()->_M_impl != L._M_impl) {
416  // this assign should be atomic, should be fixed here:
418 
419  // Set the global C locale, if appropriate.
420 #if !defined(_STLP_NO_LOCALE_SUPPORT)
421  if (L.name() != _Nameless)
422  setlocale(LC_ALL, L.name().c_str());
423 #endif
424  }
425 
426 #if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
427  return old;
428 #else
429  return old._M_impl;
430 #endif
431 }
432 
433 #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
434 const locale::category locale::none;
435 const locale::category locale::collate;
436 const locale::category locale::ctype;
437 const locale::category locale::monetary;
438 const locale::category locale::numeric;
440 const locale::category locale::messages;
441 const locale::category locale::all;
442 #endif
443 
445 
_Locale_name_hint * insert_numeric_facets(const char *&name, char *buf, _Locale_name_hint *hint)
char const * _Locale_extract_monetary_name(const char *cname, char *__buf, struct _Locale_name_hint *__hint, int *__err_code)
static void _Stl_loc_combine_names_aux(_Locale_impl *L, const char *name, const char *ctype_name, const char *time_name, const char *numeric_name, const char *collate_name, const char *monetary_name, const char *messages_name, locale::category c)
Definition: locale.cpp:189
locale::facet * insert(locale::facet *, const locale::id &n)
basic_string< char, char_traits< char >, allocator< char > > name
Definition: locale_impl.h:72
static _STLP_BEGIN_NAMESPACE const string _Nameless("*")
#define _STLP_STATIC_MUTEX
Definition: features.h:267
~locale() _STLP_NOTHROW
Definition: locale.cpp:361
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void _Stl_loc_combine_names(_Locale_impl *L, const char *name1, const char *name2, locale::category c)
Definition: locale.cpp:208
static void _STLP_FUNCTION_THROWS _STLP_CALL _M_throw_on_combine_error(const string &name)
Definition: locale.cpp:60
#define __STATIC_CAST(__x, __y)
Definition: features.h:585
void _STLP_CALL _release_Locale_impl(_Locale_impl *&loc)
_Locale_name_hint * insert_monetary_facets(const char *&name, char *buf, _Locale_name_hint *hint)
GLdouble n
Definition: glext.h:7729
locale * _Stl_get_classic_locale()
__u16 time
Definition: mkdosfs.c:366
static WCHAR name1[]
Definition: record.c:34
char const * _Locale_extract_time_name(const char *cname, char *__buf, struct _Locale_name_hint *__hint, int *__err_code)
int category
Definition: _locale.h:107
#define _STLP_VOLATILE
Definition: features.h:277
static void _STLP_FUNCTION_THROWS _STLP_CALL _M_throw_bad_cast()
bool operator()(const string &__x, const string &__y) const
Definition: locale.cpp:46
char const * _Locale_extract_collate_name(const char *cname, char *__buf, struct _Locale_name_hint *__hint, int *__err_code)
#define _STLP_LOC_NO_PLATFORM_SUPPORT
Definition: c_locale.h:102
Definition: _locale.h:75
static const locale &_STLP_CALL classic()
Definition: locale.cpp:404
char const * _Locale_extract_ctype_name(const char *cname, char *__buf, struct _Locale_name_hint *__hint, int *__err_code)
locale() _STLP_NOTHROW
Definition: locale.cpp:118
#define _STLP_LOC_NO_MEMORY
Definition: c_locale.h:103
static void _STLP_FUNCTION_THROWS _STLP_CALL _M_throw_on_creation_failure(int __err_code, const char *name, const char *facet)
Definition: locale.cpp:68
#define _STLP_UNWIND(action)
Definition: features.h:824
bool operator!=(const locale &) const
Definition: locale.cpp:398
const _CharT * c_str() const
Definition: _string.h:949
_Locale_name_hint * insert_collate_facets(const char *&name, char *buf, _Locale_name_hint *hint)
_STLP_DECLSPEC _Locale_impl *_STLP_CALL _get_Locale_impl(_Locale_impl *locimpl)
const locale & operator=(const locale &) _STLP_NOTHROW
Definition: locale.cpp:368
vector< locale::facet * > facets_vec
Definition: locale_impl.h:112
GLfloat f
Definition: glext.h:7540
#define LC_ALL
Definition: locale.h:25
_Locale_name_hint * insert_time_facets(const char *&name, char *buf, _Locale_name_hint *hint)
facet * _M_get_facet(const id &) const
Definition: locale.cpp:377
Definition: _ctype.h:58
_Locale_name_hint * insert_ctype_facets(const char *&name, char *buf, _Locale_name_hint *hint)
friend class _Locale_impl
Definition: _locale.h:200
void _M_insert(facet *__f, id &__id)
Definition: locale.cpp:127
const GLubyte * c
Definition: glext.h:8905
_Locale_name_hint * insert_messages_facets(const char *&name, char *buf, _Locale_name_hint *hint)
static void _STLP_FUNCTION_THROWS _STLP_CALL _M_throw_on_null_name()
Definition: locale.cpp:57
static bool is_C_locale_name(const char *name)
Definition: locale.cpp:31
#define _STLP_LOC_UNKNOWN_NAME
Definition: c_locale.h:101
locale * _Stl_get_global_locale()
virtual ~facet()
Definition: locale.cpp:42
static const WCHAR L[]
Definition: oid.c:1250
char const * _Locale_extract_numeric_name(const char *cname, char *__buf, struct _Locale_name_hint *__hint, int *__err_code)
#define _Locale_MAX_SIMPLE_NAME
Definition: c_locale.h:54
char string[160]
Definition: util.h:11
#define _STLP_MUTEX_INITIALIZER
Definition: _threads.h:241
DWORD hint
Definition: vfdcmd.c:88
static const locale::id & _Stl_loc_get_index(locale::id &id)
Definition: locale.cpp:102
_Locale_impl * _M_impl
Definition: _locale.h:203
static locale _STLP_CALL global(const locale &)
Definition: locale.cpp:409
#define f
Definition: ke_i.h:83
#define _STLP_END_NAMESPACE
Definition: features.h:503
string name() const
Definition: locale.cpp:388
#define _STLP_TRY
Definition: features.h:817
bool operator==(const locale &) const
Definition: locale.cpp:393
#define _STLP_THROW(x)
Definition: features.h:820
#define _STLP_LOC_UNSUPPORTED_FACET_CATEGORY
Definition: c_locale.h:100
Definition: name.c:36
char const * _Locale_extract_messages_name(const char *cname, char *__buf, struct _Locale_name_hint *__hint, int *__err_code)
#define c
Definition: ke_i.h:80
GLenum GLuint id
Definition: glext.h:5579
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define setlocale(n, s)
Definition: locale.h:46
static WCHAR name2[]
Definition: record.c:35
size_t size() const
Definition: locale_impl.h:70
#define _STLP_BEGIN_NAMESPACE
Definition: features.h:501
#define _STLP_NOTHROW
Definition: _intel.h:35
size_t __stl_atomic_t
Definition: _threads.h:232
static size_t _S_max
Definition: _locale.h:104
#define _STLP_CALL
Definition: _bc.h:131
#define _STLP_THROW_BAD_ALLOC
Definition: _new.h:116
bool __locale_do_operator_call(const locale &__loc, const basic_string< _CharT, _Traits, _Alloc > &__x, const basic_string< _CharT, _Traits, _Alloc > &__y)
Definition: _collate.h:162
facet * _M_use_facet(const id &) const
Definition: locale.cpp:381
#define _STLP_ATOMIC_INCREMENT(__x)
Definition: _sparc_atomic.h:57
GLuint const GLchar * name
Definition: glext.h:6031