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
00038 locale::locale(
const char* __s) : _M_impl(0)
00039 {
00040
if (__s)
00041 {
00042 _S_initialize();
00043
if (std::strcmp(__s,
"C") == 0 || std::strcmp(__s,
"POSIX") == 0)
00044 (_M_impl = _S_classic)->_M_add_reference();
00045
else if (std::strcmp(__s,
"") != 0)
00046 _M_impl =
new _Impl(__s, 1);
00047
else
00048 {
00049
00050
char* __env = std::getenv(
"LC_ALL");
00051
00052
if (__env && std::strcmp(__env,
"") != 0)
00053 {
00054
if (std::strcmp(__env,
"C") == 0
00055 || std::strcmp(__env,
"POSIX") == 0)
00056 (_M_impl = _S_classic)->_M_add_reference();
00057
else
00058 _M_impl =
new _Impl(__env, 1);
00059 }
00060
else
00061 {
00062
00063
string __res;
00064
char* __env = std::getenv(
"LANG");
00065
if (!__env || std::strcmp(__env,
"") == 0
00066 || std::strcmp(__env,
"C") == 0
00067 || std::strcmp(__env,
"POSIX") == 0)
00068 __res =
"C";
00069
else
00070 __res = __env;
00071
00072
00073
00074 size_t __i = 0;
00075
if (__res ==
"C")
00076
for (; __i < _S_categories_size; ++__i)
00077 {
00078 __env = std::getenv(_S_categories[__i]);
00079
if (__env && std::strcmp(__env,
"") != 0
00080 && std::strcmp(__env,
"C") != 0
00081 && std::strcmp(__env,
"POSIX") != 0)
00082
break;
00083 }
00084
else
00085
for (; __i < _S_categories_size; ++__i)
00086 {
00087 __env = std::getenv(_S_categories[__i]);
00088
if (__env && std::strcmp(__env,
"") != 0
00089 && __res != __env)
00090
break;
00091 }
00092
00093
00094
00095
if (__i < _S_categories_size)
00096 {
00097
string __str;
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
for (size_t __i = 0; __i < _S_categories_size; ++__i)
00208 {
00209 _M_names[__i] =
new char[__len + 1];
00210 std::strcpy(_M_names[__i], __s);
00211 }
00212 }
00213
else
00214 {
00215
const char* __beg = __s;
00216
for (size_t __i = 0; __i < _S_categories_size; ++__i)
00217 {
00218 __beg = std::strchr(__beg,
'=') + 1;
00219
const char* __end = std::strchr(__beg,
';');
00220
if (!__end)
00221 __end = __s + __len;
00222
char* __new =
new char[__end - __beg + 1];
00223 std::memcpy(__new, __beg, __end - __beg);
00224 __new[__end - __beg] =
'\0';
00225 _M_names[__i] = __new;
00226 }
00227 }
00228
00229
00230 _M_init_facet(
new std::ctype<char>(__cloc, 0,
false));
00231 _M_init_facet(
new codecvt<char, char, mbstate_t>(__cloc));
00232 _M_init_facet(
new numpunct<char>(__cloc));
00233 _M_init_facet(
new num_get<char>);
00234 _M_init_facet(
new num_put<char>);
00235 _M_init_facet(
new std::collate<char>(__cloc));
00236 _M_init_facet(
new moneypunct<char, false>(__cloc, __s));
00237 _M_init_facet(
new moneypunct<char, true>(__cloc, __s));
00238 _M_init_facet(
new money_get<char>);
00239 _M_init_facet(
new money_put<char>);
00240 _M_init_facet(
new __timepunct<char>(__cloc, __s));
00241 _M_init_facet(
new time_get<char>);
00242 _M_init_facet(
new time_put<char>);
00243 _M_init_facet(
new std::messages<char>(__cloc, __s));
00244
00245
#ifdef _GLIBCXX_USE_WCHAR_T
00246
_M_init_facet(
new std::ctype<wchar_t>(__cloc));
00247 _M_init_facet(
new codecvt<wchar_t, char, mbstate_t>(__cloc));
00248 _M_init_facet(
new numpunct<wchar_t>(__cloc));
00249 _M_init_facet(
new num_get<wchar_t>);
00250 _M_init_facet(
new num_put<wchar_t>);
00251 _M_init_facet(
new std::collate<wchar_t>(__cloc));
00252 _M_init_facet(
new moneypunct<wchar_t, false>(__cloc, __s));
00253 _M_init_facet(
new moneypunct<wchar_t, true>(__cloc, __s));
00254 _M_init_facet(
new money_get<wchar_t>);
00255 _M_init_facet(
new money_put<wchar_t>);
00256 _M_init_facet(
new __timepunct<wchar_t>(__cloc, __s));
00257 _M_init_facet(
new time_get<wchar_t>);
00258 _M_init_facet(
new time_put<wchar_t>);
00259 _M_init_facet(
new std::messages<wchar_t>(__cloc, __s));
00260
#endif
00261
locale::facet::_S_destroy_c_locale(__cloc);
00262 }
00263
catch(...)
00264 {
00265 locale::facet::_S_destroy_c_locale(__cloc);
00266 this->~_Impl();
00267 __throw_exception_again;
00268 }
00269 }
00270
00271
void
00272 locale::_Impl::
00273 _M_replace_categories(
const _Impl* __imp, category __cat)
00274 {
00275
for (size_t __ix = 0; __ix < _S_categories_size; ++__ix)
00276 {
00277
const category __mask = 1 << __ix;
00278
if (__mask & __cat)
00279 {
00280
00281 _M_replace_category(__imp, _S_facet_categories[__ix]);
00282
00283
if (std::strcmp(_M_names[__ix],
"*") != 0
00284 && std::strcmp(__imp->_M_names[__ix],
"*") != 0)
00285 {
00286
char* __new =
new char[std::strlen(__imp->_M_names[__ix]) + 1];
00287 std::strcpy(__new, __imp->_M_names[__ix]);
00288
delete [] _M_names[__ix];
00289 _M_names[__ix] = __new;
00290 }
00291 }
00292 }
00293 }
00294 }