OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [src/] [localename.cc] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2
// 2006, 2007, 2008, 2009
3
// Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// <http://www.gnu.org/licenses/>.
24
 
25
#include <clocale>
26
#include <cstring>
27
#include <cstdlib>
28
#include <locale>
29
 
30
_GLIBCXX_BEGIN_NAMESPACE(std)
31
 
32
  using namespace __gnu_cxx;
33
 
34
  locale::locale(const char* __s) : _M_impl(0)
35
  {
36
    if (__s)
37
      {
38
        _S_initialize();
39
        if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0)
40
          (_M_impl = _S_classic)->_M_add_reference();
41
        else if (std::strcmp(__s, "") != 0)
42
          _M_impl = new _Impl(__s, 1);
43
        else
44
          {
45
            // Get it from the environment.
46
            char* __env = std::getenv("LC_ALL");
47
            // If LC_ALL is set we are done.
48
            if (__env && std::strcmp(__env, "") != 0)
49
              {
50
                if (std::strcmp(__env, "C") == 0
51
                    || std::strcmp(__env, "POSIX") == 0)
52
                  (_M_impl = _S_classic)->_M_add_reference();
53
                else
54
                  _M_impl = new _Impl(__env, 1);
55
              }
56
            else
57
              {
58
                // LANG may set a default different from "C".
59
                string __lang;
60
                __env = std::getenv("LANG");
61
                if (!__env || std::strcmp(__env, "") == 0
62
                    || std::strcmp(__env, "C") == 0
63
                    || std::strcmp(__env, "POSIX") == 0)
64
                  __lang = "C";
65
                else
66
                  __lang = __env;
67
 
68
                // Scan the categories looking for the first one
69
                // different from LANG.
70
                size_t __i = 0;
71
                if (__lang == "C")
72
                  for (; __i < _S_categories_size; ++__i)
73
                    {
74
                      __env = std::getenv(_S_categories[__i]);
75
                      if (__env && std::strcmp(__env, "") != 0
76
                          && std::strcmp(__env, "C") != 0
77
                          && std::strcmp(__env, "POSIX") != 0)
78
                        break;
79
                    }
80
                else
81
                  for (; __i < _S_categories_size; ++__i)
82
                    {
83
                      __env = std::getenv(_S_categories[__i]);
84
                      if (__env && std::strcmp(__env, "") != 0
85
                          && __lang != __env)
86
                        break;
87
                    }
88
 
89
                // If one is found, build the complete string of
90
                // the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on...
91
                if (__i < _S_categories_size)
92
                  {
93
                    string __str;
94
                    __str.reserve(128);
95
                    for (size_t __j = 0; __j < __i; ++__j)
96
                      {
97
                        __str += _S_categories[__j];
98
                        __str += '=';
99
                        __str += __lang;
100
                        __str += ';';
101
                      }
102
                    __str += _S_categories[__i];
103
                    __str += '=';
104
                    __str += __env;
105
                    __str += ';';
106
                    ++__i;
107
                    for (; __i < _S_categories_size; ++__i)
108
                      {
109
                        __env = std::getenv(_S_categories[__i]);
110
                        __str += _S_categories[__i];
111
                        if (!__env || std::strcmp(__env, "") == 0)
112
                          {
113
                            __str += '=';
114
                            __str += __lang;
115
                            __str += ';';
116
                          }
117
                        else if (std::strcmp(__env, "C") == 0
118
                                 || std::strcmp(__env, "POSIX") == 0)
119
                          __str += "=C;";
120
                        else
121
                          {
122
                            __str += '=';
123
                            __str += __env;
124
                            __str += ';';
125
                          }
126
                      }
127
                    __str.erase(__str.end() - 1);
128
                    _M_impl = new _Impl(__str.c_str(), 1);
129
                  }
130
                // ... otherwise either an additional instance of
131
                // the "C" locale or LANG.
132
                else if (__lang == "C")
133
                  (_M_impl = _S_classic)->_M_add_reference();
134
                else
135
                  _M_impl = new _Impl(__lang.c_str(), 1);
136
              }
137
          }
138
      }
139
    else
140
      __throw_runtime_error(__N("locale::locale NULL not valid"));
141
  }
142
 
143
  locale::locale(const locale& __base, const char* __s, category __cat)
144
  : _M_impl(0)
145
  {
146
    // NB: There are complicated, yet more efficient ways to do
147
    // this. Building up locales on a per-category way is tedious, so
148
    // let's do it this way until people complain.
149
    locale __add(__s);
150
    _M_coalesce(__base, __add, __cat);
151
  }
152
 
153
  locale::locale(const locale& __base, const locale& __add, category __cat)
154
  : _M_impl(0)
155
  { _M_coalesce(__base, __add, __cat); }
156
 
157
  void
158
  locale::_M_coalesce(const locale& __base, const locale& __add,
159
                      category __cat)
160
  {
161
    __cat = _S_normalize_category(__cat);
162
    _M_impl = new _Impl(*__base._M_impl, 1);
163
 
164
    __try
165
      { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
166
    __catch(...)
167
      {
168
        _M_impl->_M_remove_reference();
169
        __throw_exception_again;
170
      }
171
  }
172
 
173
  // Construct named _Impl.
174
  locale::_Impl::
175
  _Impl(const char* __s, size_t __refs)
176
  : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
177
    _M_caches(0), _M_names(0)
178
  {
179
    // Initialize the underlying locale model, which also checks to
180
    // see if the given name is valid.
181
    __c_locale __cloc;
182
    locale::facet::_S_create_c_locale(__cloc, __s);
183
    __c_locale __clocm = __cloc;
184
 
185
    __try
186
      {
187
        _M_facets = new const facet*[_M_facets_size];
188
        for (size_t __i = 0; __i < _M_facets_size; ++__i)
189
          _M_facets[__i] = 0;
190
        _M_caches = new const facet*[_M_facets_size];
191
        for (size_t __j = 0; __j < _M_facets_size; ++__j)
192
          _M_caches[__j] = 0;
193
        _M_names = new char*[_S_categories_size];
194
        for (size_t __k = 0; __k < _S_categories_size; ++__k)
195
          _M_names[__k] = 0;
196
 
197
        // Name the categories.
198
        const char* __smon = __s;
199
        const size_t __len = std::strlen(__s);
200
        if (!std::memchr(__s, ';', __len))
201
          {
202
            _M_names[0] = new char[__len + 1];
203
            std::memcpy(_M_names[0], __s, __len + 1);
204
          }
205
        else
206
          {
207
            const char* __end = __s;
208
            bool __found_ctype = false;
209
            bool __found_monetary = false;
210
            size_t __ci = 0, __mi = 0;
211
            for (size_t __i = 0; __i < _S_categories_size; ++__i)
212
              {
213
                const char* __beg = std::strchr(__end + 1, '=') + 1;
214
                __end = std::strchr(__beg, ';');
215
                if (!__end)
216
                  __end = __s + __len;
217
                _M_names[__i] = new char[__end - __beg + 1];
218
                std::memcpy(_M_names[__i], __beg, __end - __beg);
219
                _M_names[__i][__end - __beg] = '\0';
220
                if (!__found_ctype
221
                    && *(__beg - 2) == 'E' && *(__beg - 3) == 'P')
222
                  {
223
                    __found_ctype = true;
224
                    __ci = __i;
225
                  }
226
                else if (!__found_monetary && *(__beg - 2) == 'Y')
227
                  {
228
                    __found_monetary = true;
229
                    __mi = __i;
230
                  }
231
              }
232
 
233
            if (std::strcmp(_M_names[__ci], _M_names[__mi]))
234
              {
235
                __smon = _M_names[__mi];
236
                __clocm = locale::facet::_S_lc_ctype_c_locale(__cloc,
237
                                                              __smon);
238
              }
239
          }
240
 
241
        // Construct all standard facets and add them to _M_facets.
242
        _M_init_facet(new std::ctype<char>(__cloc, 0, false));
243
        _M_init_facet(new codecvt<char, char, mbstate_t>(__cloc));
244
        _M_init_facet(new numpunct<char>(__cloc));
245
        _M_init_facet(new num_get<char>);
246
        _M_init_facet(new num_put<char>);
247
        _M_init_facet(new std::collate<char>(__cloc));
248
        _M_init_facet(new moneypunct<char, false>(__cloc, 0));
249
        _M_init_facet(new moneypunct<char, true>(__cloc, 0));
250
        _M_init_facet(new money_get<char>);
251
        _M_init_facet(new money_put<char>);
252
        _M_init_facet(new __timepunct<char>(__cloc, __s));
253
        _M_init_facet(new time_get<char>);
254
        _M_init_facet(new time_put<char>);
255
        _M_init_facet(new std::messages<char>(__cloc, __s));
256
 
257
#ifdef  _GLIBCXX_USE_WCHAR_T
258
        _M_init_facet(new std::ctype<wchar_t>(__cloc));
259
        _M_init_facet(new codecvt<wchar_t, char, mbstate_t>(__cloc));
260
        _M_init_facet(new numpunct<wchar_t>(__cloc));
261
        _M_init_facet(new num_get<wchar_t>);
262
        _M_init_facet(new num_put<wchar_t>);
263
        _M_init_facet(new std::collate<wchar_t>(__cloc));
264
        _M_init_facet(new moneypunct<wchar_t, false>(__clocm, __smon));
265
        _M_init_facet(new moneypunct<wchar_t, true>(__clocm, __smon));
266
        _M_init_facet(new money_get<wchar_t>);
267
        _M_init_facet(new money_put<wchar_t>);
268
        _M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
269
        _M_init_facet(new time_get<wchar_t>);
270
        _M_init_facet(new time_put<wchar_t>);
271
        _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
272
#endif    
273
        locale::facet::_S_destroy_c_locale(__cloc);
274
        if (__clocm != __cloc)
275
          locale::facet::_S_destroy_c_locale(__clocm);
276
      }
277
    __catch(...)
278
      {
279
        locale::facet::_S_destroy_c_locale(__cloc);
280
        if (__clocm != __cloc)
281
          locale::facet::_S_destroy_c_locale(__clocm);
282
        this->~_Impl();
283
        __throw_exception_again;
284
      }
285
  }
286
 
287
  void
288
  locale::_Impl::
289
  _M_replace_categories(const _Impl* __imp, category __cat)
290
  {
291
    category __mask = 1;
292
    if (!_M_names[0] || !__imp->_M_names[0])
293
      {
294
        if (_M_names[0])
295
          {
296
            delete [] _M_names[0];
297
            _M_names[0] = 0;   // Unnamed.
298
          }
299
 
300
        for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
301
          {
302
            if (__mask & __cat)
303
              // Need to replace entry in _M_facets with other locale's info.
304
              _M_replace_category(__imp, _S_facet_categories[__ix]);
305
          }
306
      }
307
    else
308
      {
309
        if (!_M_names[1])
310
          {
311
            // A full set of _M_names must be prepared, all identical
312
            // to _M_names[0] to begin with. Then, below, a few will
313
            // be replaced by the corresponding __imp->_M_names. I.e.,
314
            // not a "simple" locale anymore (see locale::operator==).
315
            const size_t __len = std::strlen(_M_names[0]) + 1;
316
            for (size_t __i = 1; __i < _S_categories_size; ++__i)
317
              {
318
                _M_names[__i] = new char[__len];
319
                std::memcpy(_M_names[__i], _M_names[0], __len);
320
              }
321
          }
322
 
323
        for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
324
          {
325
            if (__mask & __cat)
326
              {
327
                // Need to replace entry in _M_facets with other locale's info.
328
                _M_replace_category(__imp, _S_facet_categories[__ix]);
329
 
330
                // FIXME: Hack for libstdc++/29217: the numerical encodings
331
                // of the time and collate categories are swapped vs the
332
                // order of the names in locale::_S_categories.  We'd like to
333
                // adjust the former (the latter is dictated by compatibility
334
                // with glibc) but we can't for binary compatibility.
335
                size_t __ix_name = __ix;
336
                if (__ix == 2 || __ix == 3)
337
                  __ix_name = 5 - __ix;
338
 
339
                char* __src = __imp->_M_names[__ix_name] ?
340
                              __imp->_M_names[__ix_name] : __imp->_M_names[0];
341
                const size_t __len = std::strlen(__src) + 1;
342
                char* __new = new char[__len];
343
                std::memcpy(__new, __src, __len);
344
                delete [] _M_names[__ix_name];
345
                _M_names[__ix_name] = __new;
346
              }
347
          }
348
      }
349
  }
350
 
351
_GLIBCXX_END_NAMESPACE

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.