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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [src/] [localename.cc] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 jlechner
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
2
// Free Software Foundation, Inc.
3
//
4
// This file is part of the GNU ISO C++ Library.  This library is free
5
// software; you can redistribute it and/or modify it under the
6
// terms of the GNU General Public License as published by the
7
// Free Software Foundation; either version 2, or (at your option)
8
// any later version.
9
 
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
 
15
// You should have received a copy of the GNU General Public License along
16
// with this library; see the file COPYING.  If not, write to the Free
17
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
18
// USA.
19
 
20
// As a special exception, you may use this file as part of a free software
21
// library without restriction.  Specifically, if other files instantiate
22
// templates or use macros or inline functions from this file, or you compile
23
// this file and link it with other files to produce an executable, this
24
// file does not by itself cause the resulting executable to be covered by
25
// the GNU General Public License.  This exception does not however
26
// invalidate any other reasons why the executable file might be covered by
27
// the GNU General Public License.
28
 
29
#include <clocale>
30
#include <cstring>
31
#include <locale>
32
 
33
namespace std
34
{
35
  using namespace __gnu_cxx;
36
 
37
  locale::locale(const char* __s) : _M_impl(0)
38
  {
39
    if (__s)
40
      {
41
        _S_initialize();
42
        if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0)
43
          (_M_impl = _S_classic)->_M_add_reference();
44
        else if (std::strcmp(__s, "") != 0)
45
          _M_impl = new _Impl(__s, 1);
46
        else
47
          {
48
            // Get it from the environment.
49
            char* __env = std::getenv("LC_ALL");
50
            // If LC_ALL is set we are done.
51
            if (__env && std::strcmp(__env, "") != 0)
52
              {
53
                if (std::strcmp(__env, "C") == 0
54
                    || std::strcmp(__env, "POSIX") == 0)
55
                  (_M_impl = _S_classic)->_M_add_reference();
56
                else
57
                  _M_impl = new _Impl(__env, 1);
58
              }
59
            else
60
              {
61
                // LANG may set a default different from "C".
62
                string __lang;
63
                __env = std::getenv("LANG");
64
                if (!__env || std::strcmp(__env, "") == 0
65
                    || std::strcmp(__env, "C") == 0
66
                    || std::strcmp(__env, "POSIX") == 0)
67
                  __lang = "C";
68
                else
69
                  __lang = __env;
70
 
71
                // Scan the categories looking for the first one
72
                // different from LANG.
73
                size_t __i = 0;
74
                if (__lang == "C")
75
                  for (; __i < _S_categories_size; ++__i)
76
                    {
77
                      __env = std::getenv(_S_categories[__i]);
78
                      if (__env && std::strcmp(__env, "") != 0
79
                          && std::strcmp(__env, "C") != 0
80
                          && std::strcmp(__env, "POSIX") != 0)
81
                        break;
82
                    }
83
                else
84
                  for (; __i < _S_categories_size; ++__i)
85
                    {
86
                      __env = std::getenv(_S_categories[__i]);
87
                      if (__env && std::strcmp(__env, "") != 0
88
                          && __lang != __env)
89
                        break;
90
                    }
91
 
92
                // If one is found, build the complete string of
93
                // the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on...
94
                if (__i < _S_categories_size)
95
                  {
96
                    string __str;
97
                    __str.reserve(128);
98
                    for (size_t __j = 0; __j < __i; ++__j)
99
                      {
100
                        __str += _S_categories[__j];
101
                        __str += '=';
102
                        __str += __lang;
103
                        __str += ';';
104
                      }
105
                    __str += _S_categories[__i];
106
                    __str += '=';
107
                    __str += __env;
108
                    __str += ';';
109
                    ++__i;
110
                    for (; __i < _S_categories_size; ++__i)
111
                      {
112
                        __env = std::getenv(_S_categories[__i]);
113
                        __str += _S_categories[__i];
114
                        if (!__env || std::strcmp(__env, "") == 0)
115
                          {
116
                            __str += '=';
117
                            __str += __lang;
118
                            __str += ';';
119
                          }
120
                        else if (std::strcmp(__env, "C") == 0
121
                                 || std::strcmp(__env, "POSIX") == 0)
122
                          __str += "=C;";
123
                        else
124
                          {
125
                            __str += '=';
126
                            __str += __env;
127
                            __str += ';';
128
                          }
129
                      }
130
                    __str.erase(__str.end() - 1);
131
                    _M_impl = new _Impl(__str.c_str(), 1);
132
                  }
133
                // ... otherwise either an additional instance of
134
                // the "C" locale or LANG.
135
                else if (__lang == "C")
136
                  (_M_impl = _S_classic)->_M_add_reference();
137
                else
138
                  _M_impl = new _Impl(__lang.c_str(), 1);
139
              }
140
          }
141
      }
142
    else
143
      __throw_runtime_error(__N("locale::locale NULL not valid"));
144
  }
145
 
146
  locale::locale(const locale& __base, const char* __s, category __cat)
147
  : _M_impl(0)
148
  {
149
    // NB: There are complicated, yet more efficient ways to do
150
    // this. Building up locales on a per-category way is tedious, so
151
    // let's do it this way until people complain.
152
    locale __add(__s);
153
    _M_coalesce(__base, __add, __cat);
154
  }
155
 
156
  locale::locale(const locale& __base, const locale& __add, category __cat)
157
  : _M_impl(0)
158
  { _M_coalesce(__base, __add, __cat); }
159
 
160
  void
161
  locale::_M_coalesce(const locale& __base, const locale& __add,
162
                      category __cat)
163
  {
164
    __cat = _S_normalize_category(__cat);
165
    _M_impl = new _Impl(*__base._M_impl, 1);
166
 
167
    try
168
      { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
169
    catch (...)
170
      {
171
        _M_impl->_M_remove_reference();
172
        __throw_exception_again;
173
      }
174
  }
175
 
176
  // Construct named _Impl.
177
  locale::_Impl::
178
  _Impl(const char* __s, size_t __refs)
179
  : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
180
    _M_caches(0), _M_names(0)
181
  {
182
    // Initialize the underlying locale model, which also checks to
183
    // see if the given name is valid.
184
    __c_locale __cloc;
185
    locale::facet::_S_create_c_locale(__cloc, __s);
186
 
187
    try
188
      {
189
        _M_facets = new const facet*[_M_facets_size];
190
        for (size_t __i = 0; __i < _M_facets_size; ++__i)
191
          _M_facets[__i] = 0;
192
        _M_caches = new const facet*[_M_facets_size];
193
        for (size_t __j = 0; __j < _M_facets_size; ++__j)
194
          _M_caches[__j] = 0;
195
        _M_names = new char*[_S_categories_size];
196
        for (size_t __k = 0; __k < _S_categories_size; ++__k)
197
          _M_names[__k] = 0;
198
 
199
        // Name the categories.
200
        const size_t __len = std::strlen(__s);
201
        if (!std::memchr(__s, ';', __len))
202
          {
203
            _M_names[0] = new char[__len + 1];
204
            std::memcpy(_M_names[0], __s, __len + 1);
205
          }
206
        else
207
          {
208
            const char* __end = __s;
209
            for (size_t __i = 0; __i < _S_categories_size; ++__i)
210
              {
211
                const char* __beg = std::strchr(__end + 1, '=') + 1;
212
                __end = std::strchr(__beg, ';');
213
                if (!__end)
214
                  __end = __s + __len;
215
                _M_names[__i] = new char[__end - __beg + 1];
216
                std::memcpy(_M_names[__i], __beg, __end - __beg);
217
                _M_names[__i][__end - __beg] = '\0';
218
              }
219
          }
220
 
221
        // Construct all standard facets and add them to _M_facets.
222
        _M_init_facet(new std::ctype<char>(__cloc, 0, false));
223
        _M_init_facet(new codecvt<char, char, mbstate_t>(__cloc));
224
        _M_init_facet(new numpunct<char>(__cloc));
225
        _M_init_facet(new num_get<char>);
226
        _M_init_facet(new num_put<char>);
227
        _M_init_facet(new std::collate<char>(__cloc));
228
        _M_init_facet(new moneypunct<char, false>(__cloc, __s));
229
        _M_init_facet(new moneypunct<char, true>(__cloc, __s));
230
        _M_init_facet(new money_get<char>);
231
        _M_init_facet(new money_put<char>);
232
        _M_init_facet(new __timepunct<char>(__cloc, __s));
233
        _M_init_facet(new time_get<char>);
234
        _M_init_facet(new time_put<char>);
235
        _M_init_facet(new std::messages<char>(__cloc, __s));
236
 
237
#ifdef  _GLIBCXX_USE_WCHAR_T
238
        _M_init_facet(new std::ctype<wchar_t>(__cloc));
239
        _M_init_facet(new codecvt<wchar_t, char, mbstate_t>(__cloc));
240
        _M_init_facet(new numpunct<wchar_t>(__cloc));
241
        _M_init_facet(new num_get<wchar_t>);
242
        _M_init_facet(new num_put<wchar_t>);
243
        _M_init_facet(new std::collate<wchar_t>(__cloc));
244
        _M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
245
        _M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
246
        _M_init_facet(new money_get<wchar_t>);
247
        _M_init_facet(new money_put<wchar_t>);
248
        _M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
249
        _M_init_facet(new time_get<wchar_t>);
250
        _M_init_facet(new time_put<wchar_t>);
251
        _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
252
#endif    
253
        locale::facet::_S_destroy_c_locale(__cloc);
254
      }
255
    catch(...)
256
      {
257
        locale::facet::_S_destroy_c_locale(__cloc);
258
        this->~_Impl();
259
        __throw_exception_again;
260
      }
261
  }
262
 
263
  void
264
  locale::_Impl::
265
  _M_replace_categories(const _Impl* __imp, category __cat)
266
  {
267
    category __mask = 1;
268
    const bool __have_names = _M_names[0] && __imp->_M_names[0];
269
    for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
270
      {
271
        if (__mask & __cat)
272
          {
273
            // Need to replace entry in _M_facets with other locale's info.
274
            _M_replace_category(__imp, _S_facet_categories[__ix]);
275
            // If both have names, go ahead and mangle.
276
            if (__have_names)
277
              {
278
                if (!_M_names[1])
279
                  {
280
                    // A full set of _M_names must be prepared, all identical
281
                    // to _M_names[0] to begin with. Then, below, a few will
282
                    // be replaced by the corresponding __imp->_M_names. I.e.,
283
                    // not a "simple" locale anymore (see locale::operator==).
284
                    const size_t __len = std::strlen(_M_names[0]) + 1;
285
                    for (size_t __i = 1; __i < _S_categories_size; ++__i)
286
                      {
287
                        _M_names[__i] = new char[__len];
288
                        std::memcpy(_M_names[__i], _M_names[0], __len);
289
                      }
290
                  }
291
                char* __src = __imp->_M_names[__ix] ? __imp->_M_names[__ix]
292
                                                    : __imp->_M_names[0];
293
                const size_t __len = std::strlen(__src) + 1;
294
                char* __new = new char[__len];
295
                std::memcpy(__new, __src, __len);
296
                delete [] _M_names[__ix];
297
                _M_names[__ix] = __new;
298
              }
299
          }
300
      }
301
  }
302
} // namespace std

powered by: WebSVN 2.1.0

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