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