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* __end = __s;
00216 for (size_t __i = 0; __i < _S_categories_size; ++__i)
00217 {
00218 const char* __beg = std::strchr(__end + 1, '=') + 1;
00219 __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 }