00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
#include <clocale>
00030
#include <cstring>
00031
#include <locale>
00032
00033
namespace std
00034 {
00035
using namespace __gnu_cxx;
00036
00037 locale::locale(
const char* __s) : _M_impl(0)
00038 {
00039
if (__s)
00040 {
00041 _S_initialize();
00042
if (std::strcmp(__s,
"C") == 0 || std::strcmp(__s,
"POSIX") == 0)
00043 (_M_impl = _S_classic)->_M_add_reference();
00044
else if (std::strcmp(__s,
"") != 0)
00045 _M_impl =
new _Impl(__s, 1);
00046
else
00047 {
00048
00049
char* __env = std::getenv(
"LC_ALL");
00050
00051
if (__env && std::strcmp(__env,
"") != 0)
00052 {
00053
if (std::strcmp(__env,
"C") == 0
00054 || std::strcmp(__env,
"POSIX") == 0)
00055 (_M_impl = _S_classic)->_M_add_reference();
00056
else
00057 _M_impl =
new _Impl(__env, 1);
00058 }
00059
else
00060 {
00061
00062
string __res;
00063
char* __env = std::getenv(
"LANG");
00064
if (!__env || std::strcmp(__env,
"") == 0
00065 || std::strcmp(__env,
"C") == 0
00066 || std::strcmp(__env,
"POSIX") == 0)
00067 __res =
"C";
00068
else
00069 __res = __env;
00070
00071
00072
00073 size_t __i = 0;
00074
if (__res ==
"C")
00075
for (; __i < _S_categories_size; ++__i)
00076 {
00077 __env = std::getenv(_S_categories[__i]);
00078
if (__env && std::strcmp(__env,
"") != 0
00079 && std::strcmp(__env,
"C") != 0
00080 && std::strcmp(__env,
"POSIX") != 0)
00081
break;
00082 }
00083
else
00084
for (; __i < _S_categories_size; ++__i)
00085 {
00086 __env = std::getenv(_S_categories[__i]);
00087
if (__env && std::strcmp(__env,
"") != 0
00088 && __res != __env)
00089
break;
00090 }
00091
00092
00093
00094
if (__i < _S_categories_size)
00095 {
00096
string __str;
00097 __str.
reserve(128);
00098
for (size_t __j = 0; __j < __i; ++__j)
00099 {
00100 __str += _S_categories[__j];
00101 __str +=
'=';
00102 __str += __res;
00103 __str +=
';';
00104 }
00105 __str += _S_categories[__i];
00106 __str +=
'=';
00107 __str += __env;
00108 __str +=
';';
00109 __i++;
00110
for (; __i < _S_categories_size; ++__i)
00111 {
00112 __env = std::getenv(_S_categories[__i]);
00113
if (!__env || std::strcmp(__env,
"") == 0)
00114 {
00115 __str += _S_categories[__i];
00116 __str +=
'=';
00117 __str += __res;
00118 __str +=
';';
00119 }
00120
else if (std::strcmp(__env,
"C") == 0
00121 || std::strcmp(__env,
"POSIX") == 0)
00122 {
00123 __str += _S_categories[__i];
00124 __str +=
"=C;";
00125 }
00126
else
00127 {
00128 __str += _S_categories[__i];
00129 __str +=
'=';
00130 __str += __env;
00131 __str +=
';';
00132 }
00133 }
00134 __str.
erase(__str.
end() - 1);
00135 _M_impl =
new _Impl(__str.
c_str(), 1);
00136 }
00137
00138
00139
else if (__res ==
"C")
00140 (_M_impl = _S_classic)->_M_add_reference();
00141
else
00142 _M_impl =
new _Impl(__res.
c_str(), 1);
00143 }
00144 }
00145 }
00146
else
00147 __throw_runtime_error(__N(
"locale::locale NULL not valid"));
00148 }
00149
00150 locale::locale(
const locale& __base,
const char* __s, category __cat)
00151 : _M_impl(0)
00152 {
00153
00154
00155
00156
locale __add(__s);
00157 _M_coalesce(__base, __add, __cat);
00158 }
00159
00160 locale::locale(
const locale& __base,
const locale& __add, category __cat)
00161 : _M_impl(0)
00162 { _M_coalesce(__base, __add, __cat); }
00163
00164
void
00165 locale::_M_coalesce(
const locale& __base,
const locale& __add,
00166 category __cat)
00167 {
00168 __cat = _S_normalize_category(__cat);
00169 _M_impl =
new _Impl(*__base._M_impl, 1);
00170
00171
try
00172 { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
00173
catch (...)
00174 {
00175 _M_impl->_M_remove_reference();
00176 __throw_exception_again;
00177 }
00178 }
00179
00180
00181 locale::_Impl::
00182 _Impl(
const char* __s, size_t __refs)
00183 : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
00184 _M_caches(0), _M_names(0)
00185 {
00186
00187
00188 __c_locale __cloc;
00189 locale::facet::_S_create_c_locale(__cloc, __s);
00190
00191
try
00192 {
00193 _M_facets =
new const facet*[_M_facets_size];
00194
for (size_t __i = 0; __i < _M_facets_size; ++__i)
00195 _M_facets[__i] = 0;
00196 _M_caches =
new const facet*[_M_facets_size];
00197
for (size_t __j = 0; __j < _M_facets_size; ++__j)
00198 _M_caches[__j] = 0;
00199 _M_names =
new char*[_S_categories_size];
00200
for (size_t __k = 0; __k < _S_categories_size; ++__k)
00201 _M_names[__k] = 0;
00202
00203
00204
const size_t __len = std::strlen(__s);
00205
if (!std::strchr(__s,
';'))
00206 {
00207 _M_names[0] =
new char[__len + 1];
00208 std::memcpy(_M_names[0], __s, __len + 1);
00209 }
00210
else
00211 {
00212
const char* __beg = __s;
00213
for (size_t __i = 0; __i < _S_categories_size; ++__i)
00214 {
00215 __beg = std::strchr(__beg,
'=') + 1;
00216
const char* __end = std::strchr(__beg,
';');
00217
if (!__end)
00218 __end = __s + __len;
00219 _M_names[__i] =
new char[__end - __beg + 1];
00220 std::memcpy(_M_names[__i], __beg, __end - __beg);
00221 _M_names[__i][__end - __beg] =
'\0';
00222 }
00223 }
00224
00225
00226 _M_init_facet(
new std::ctype<char>(__cloc, 0,
false));
00227 _M_init_facet(
new codecvt<char, char, mbstate_t>(__cloc));
00228 _M_init_facet(
new numpunct<char>(__cloc));
00229 _M_init_facet(
new num_get<char>);
00230 _M_init_facet(
new num_put<char>);
00231 _M_init_facet(
new std::collate<char>(__cloc));
00232 _M_init_facet(
new moneypunct<char, false>(__cloc, __s));
00233 _M_init_facet(
new moneypunct<char, true>(__cloc, __s));
00234 _M_init_facet(
new money_get<char>);
00235 _M_init_facet(
new money_put<char>);
00236 _M_init_facet(
new __timepunct<char>(__cloc, __s));
00237 _M_init_facet(
new time_get<char>);
00238 _M_init_facet(
new time_put<char>);
00239 _M_init_facet(
new std::messages<char>(__cloc, __s));
00240
00241
#ifdef _GLIBCXX_USE_WCHAR_T
00242
_M_init_facet(
new std::ctype<wchar_t>(__cloc));
00243 _M_init_facet(
new codecvt<wchar_t, char, mbstate_t>(__cloc));
00244 _M_init_facet(
new numpunct<wchar_t>(__cloc));
00245 _M_init_facet(
new num_get<wchar_t>);
00246 _M_init_facet(
new num_put<wchar_t>);
00247 _M_init_facet(
new std::collate<wchar_t>(__cloc));
00248 _M_init_facet(
new moneypunct<wchar_t, false>(__cloc, __s));
00249 _M_init_facet(
new moneypunct<wchar_t, true>(__cloc, __s));
00250 _M_init_facet(
new money_get<wchar_t>);
00251 _M_init_facet(
new money_put<wchar_t>);
00252 _M_init_facet(
new __timepunct<wchar_t>(__cloc, __s));
00253 _M_init_facet(
new time_get<wchar_t>);
00254 _M_init_facet(
new time_put<wchar_t>);
00255 _M_init_facet(
new std::messages<wchar_t>(__cloc, __s));
00256
#endif
00257
locale::facet::_S_destroy_c_locale(__cloc);
00258 }
00259
catch(...)
00260 {
00261 locale::facet::_S_destroy_c_locale(__cloc);
00262 this->~_Impl();
00263 __throw_exception_again;
00264 }
00265 }
00266
00267
void
00268 locale::_Impl::
00269 _M_replace_categories(
const _Impl* __imp, category __cat)
00270 {
00271
category __mask = 1;
00272
const bool __have_names = _M_names[0] && __imp->_M_names[0];
00273
for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
00274 {
00275
if (__mask & __cat)
00276 {
00277
00278 _M_replace_category(__imp, _S_facet_categories[__ix]);
00279
00280
if (__have_names)
00281 {
00282
if (!_M_names[1])
00283 {
00284
00285
00286
00287
00288
const size_t __len = std::strlen(_M_names[0]) + 1;
00289
for (size_t __i = 1; __i < _S_categories_size; ++__i)
00290 {
00291 _M_names[__i] =
new char[__len];
00292 std::memcpy(_M_names[__i], _M_names[0], __len);
00293 }
00294 }
00295
char* __src = __imp->_M_names[__ix] ? __imp->_M_names[__ix]
00296 : __imp->_M_names[0];
00297
const size_t __len = std::strlen(__src) + 1;
00298
char* __new =
new char[__len];
00299 std::memcpy(__new, __src, __len);
00300
delete [] _M_names[__ix];
00301 _M_names[__ix] = __new;
00302 }
00303 }
00304 }
00305 }
00306 }