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 __gnu_cxx
00034 {
00035 using namespace std;
00036
00037
00038 extern locale::facet* facet_vec[_GLIBCPP_NUM_FACETS];
00039 extern locale::facet* facet_cache_vec[2 * _GLIBCPP_NUM_FACETS];
00040 extern char* facet_name[6 + _GLIBCPP_NUM_CATEGORIES];
00041
00042 extern std::ctype<char> ctype_c;
00043 extern std::collate<char> collate_c;
00044 extern numpunct<char> numpunct_c;
00045 extern num_get<char> num_get_c;
00046 extern num_put<char> num_put_c;
00047 extern codecvt<char, char, mbstate_t> codecvt_c;
00048 extern moneypunct<char, false> moneypunct_fc;
00049 extern moneypunct<char, true> moneypunct_tc;
00050 extern money_get<char> money_get_c;
00051 extern money_put<char> money_put_c;
00052 extern __timepunct<char> timepunct_c;
00053 extern time_get<char> time_get_c;
00054 extern time_put<char> time_put_c;
00055 extern std::messages<char> messages_c;
00056 #ifdef _GLIBCPP_USE_WCHAR_T
00057 extern std::ctype<wchar_t> ctype_w;
00058 extern std::collate<wchar_t> collate_w;
00059 extern numpunct<wchar_t> numpunct_w;
00060 extern num_get<wchar_t> num_get_w;
00061 extern num_put<wchar_t> num_put_w;
00062 extern codecvt<wchar_t, char, mbstate_t> codecvt_w;
00063 extern moneypunct<wchar_t, false> moneypunct_fw;
00064 extern moneypunct<wchar_t, true> moneypunct_tw;
00065 extern money_get<wchar_t> money_get_w;
00066 extern money_put<wchar_t> money_put_w;
00067 extern __timepunct<wchar_t> timepunct_w;
00068 extern time_get<wchar_t> time_get_w;
00069 extern time_put<wchar_t> time_put_w;
00070 extern std::messages<wchar_t> messages_w;
00071 #endif
00072
00073 extern std::__locale_cache<numpunct<char> > locale_cache_np_c;
00074 #ifdef _GLIBCPP_USE_WCHAR_T
00075 extern std::__locale_cache<numpunct<wchar_t> > locale_cache_np_w;
00076 #endif
00077 }
00078
00079 namespace std
00080 {
00081 using namespace __gnu_cxx;
00082
00083 locale::_Impl::
00084 ~_Impl() throw()
00085 {
00086
00087 for (size_t __i = 0; __i < _M_facets_size; ++__i)
00088 if (_M_facets[__i])
00089 _M_facets[__i]->_M_remove_reference();
00090 for (size_t __i = _M_facets_size; __i < 2*_M_facets_size; ++__i)
00091 if (_M_facets[__i])
00092 delete (__locale_cache_base*)_M_facets[__i];
00093 delete [] _M_facets;
00094
00095 for (size_t __i = 0;
00096 __i < _S_categories_size + _S_extra_categories_size; ++__i)
00097 delete [] _M_names[__i];
00098 }
00099
00100
00101 locale::_Impl::
00102 _Impl(const _Impl& __imp, size_t __refs)
00103 : _M_references(__refs), _M_facets_size(__imp._M_facets_size)
00104 {
00105 try
00106 {
00107
00108 _M_facets = new facet*[2*_M_facets_size];
00109 for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
00110 _M_facets[__i] = 0;
00111 }
00112 catch(...)
00113 {
00114 delete [] _M_facets;
00115 __throw_exception_again;
00116 }
00117 for (size_t __i = 0; __i < _M_facets_size; ++__i)
00118 {
00119 _M_facets[__i] = __imp._M_facets[__i];
00120 if (_M_facets[__i])
00121 _M_facets[__i]->_M_add_reference();
00122 }
00123 for (size_t __i = 0;
00124 __i < _S_categories_size + _S_extra_categories_size; ++__i)
00125 {
00126 char* __new = new char[strlen(__imp._M_names[__i]) + 1];
00127 strcpy(__new, __imp._M_names[__i]);
00128 _M_names[__i] = __new;
00129 }
00130 }
00131
00132
00133 locale::_Impl::
00134 _Impl(const char* __s, size_t __refs)
00135 : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS)
00136 {
00137
00138
00139 __c_locale __cloc;
00140 locale::facet::_S_create_c_locale(__cloc, __s);
00141
00142 try
00143 {
00144
00145 _M_facets = new facet*[2*_M_facets_size];
00146 for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
00147 _M_facets[__i] = 0;
00148 }
00149 catch(...)
00150 {
00151 delete [] _M_facets;
00152 __throw_exception_again;
00153 }
00154
00155
00156 size_t __len = strlen(__s);
00157 if (!strchr(__s, ';'))
00158 {
00159 for (size_t __i = 0;
00160 __i < _S_categories_size + _S_extra_categories_size; ++__i)
00161 {
00162 _M_names[__i] = new char[__len + 1];
00163 strcpy(_M_names[__i], __s);
00164 }
00165 }
00166 else
00167 {
00168 const char* __beg = __s;
00169 for (size_t __i = 0;
00170 __i < _S_categories_size + _S_extra_categories_size; ++__i)
00171 {
00172 __beg = strchr(__beg, '=') + 1;
00173 const char* __end = strchr(__beg, ';');
00174 if (!__end)
00175 __end = __s + __len;
00176 char* __new = new char[__end - __beg + 1];
00177 memcpy(__new, __beg, __end - __beg);
00178 __new[__end - __beg] = '\0';
00179 _M_names[__i] = __new;
00180 }
00181 }
00182
00183
00184 _M_init_facet(new std::ctype<char>(__cloc, 0, false));
00185 _M_init_facet(new codecvt<char, char, mbstate_t>);
00186 _M_init_facet(new numpunct<char>(__cloc));
00187 _M_init_facet(new num_get<char>);
00188 _M_init_facet(new num_put<char>);
00189 _M_init_facet(new std::collate<char>(__cloc));
00190 _M_init_facet(new moneypunct<char, false>(__cloc, __s));
00191 _M_init_facet(new moneypunct<char, true>(__cloc, __s));
00192 _M_init_facet(new money_get<char>);
00193 _M_init_facet(new money_put<char>);
00194 _M_init_facet(new __timepunct<char>(__cloc, __s));
00195 _M_init_facet(new time_get<char>);
00196 _M_init_facet(new time_put<char>);
00197 _M_init_facet(new std::messages<char>(__cloc, __s));
00198
00199 #ifdef _GLIBCPP_USE_WCHAR_T
00200 _M_init_facet(new std::ctype<wchar_t>(__cloc));
00201 _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
00202 _M_init_facet(new numpunct<wchar_t>(__cloc));
00203 _M_init_facet(new num_get<wchar_t>);
00204 _M_init_facet(new num_put<wchar_t>);
00205 _M_init_facet(new std::collate<wchar_t>(__cloc));
00206 _M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
00207 _M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
00208 _M_init_facet(new money_get<wchar_t>);
00209 _M_init_facet(new money_put<wchar_t>);
00210 _M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
00211 _M_init_facet(new time_get<wchar_t>);
00212 _M_init_facet(new time_put<wchar_t>);
00213 _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
00214 #endif
00215 locale::facet::_S_destroy_c_locale(__cloc);
00216 }
00217
00218
00219 locale::_Impl::
00220 _Impl(facet**, size_t __refs, bool)
00221 : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS)
00222 {
00223
00224 locale::facet::_S_c_name[0] = 'C';
00225 locale::facet::_S_c_name[1] = '\0';
00226 locale::facet::_S_create_c_locale(locale::facet::_S_c_locale,
00227 locale::facet::_S_c_name);
00228
00229
00230 _M_facets = new(&facet_cache_vec) facet*[2*_M_facets_size];
00231 for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
00232 _M_facets[__i] = 0;
00233
00234
00235 for (size_t __i = 0;
00236 __i < _S_categories_size + _S_extra_categories_size; ++__i)
00237 {
00238 _M_names[__i] = new (&facet_name[__i]) char[2];
00239 strcpy(_M_names[__i], locale::facet::_S_c_name);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
00250 _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
00251 _M_init_facet(new (&numpunct_c) numpunct<char>(1));
00252 _M_init_facet(new (&num_get_c) num_get<char>(1));
00253 _M_init_facet(new (&num_put_c) num_put<char>(1));
00254 _M_init_facet(new (&collate_c) std::collate<char>(1));
00255 _M_init_facet(new (&moneypunct_fc) moneypunct<char, false>(1));
00256 _M_init_facet(new (&moneypunct_tc) moneypunct<char, true>(1));
00257 _M_init_facet(new (&money_get_c) money_get<char>(1));
00258 _M_init_facet(new (&money_put_c) money_put<char>(1));
00259 _M_init_facet(new (&timepunct_c) __timepunct<char>(1));
00260 _M_init_facet(new (&time_get_c) time_get<char>(1));
00261 _M_init_facet(new (&time_put_c) time_put<char>(1));
00262 _M_init_facet(new (&messages_c) std::messages<char>(1));
00263 #ifdef _GLIBCPP_USE_WCHAR_T
00264 _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
00265 _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
00266 _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(1));
00267 _M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
00268 _M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
00269 _M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
00270 _M_init_facet(new (&moneypunct_fw) moneypunct<wchar_t, false>(1));
00271 _M_init_facet(new (&moneypunct_tw) moneypunct<wchar_t, true>(1));
00272 _M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
00273 _M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
00274 _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(1));
00275 _M_init_facet(new (&time_get_w) time_get<wchar_t>(1));
00276 _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
00277 _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
00278 #endif
00279
00280
00281
00282 locale ltmp(this);
00283 _M_add_reference();
00284
00285
00286
00287 __locale_cache<numpunct<char> >* __lc =
00288 new (&locale_cache_np_c) __locale_cache<numpunct<char> >(ltmp, true);
00289 _M_facets[numpunct<char>::id._M_id() + _M_facets_size] =
00290 reinterpret_cast<locale::facet*>(__lc);
00291
00292 #ifdef _GLIBCPP_USE_WCHAR_T
00293 __locale_cache<numpunct<wchar_t> >* __wlc =
00294 new (&locale_cache_np_w) __locale_cache<numpunct<wchar_t> >(ltmp, true);
00295 _M_facets[numpunct<wchar_t>::id._M_id() + _M_facets_size] =
00296 reinterpret_cast<locale::facet*>(__wlc);
00297 #endif
00298 }
00299
00300 void
00301 locale::_Impl::
00302 _M_replace_categories(const _Impl* __imp, category __cat)
00303 {
00304 category __mask;
00305 for (size_t __ix = 0; __ix < _S_categories_size; ++__ix)
00306 {
00307 __mask = 1 << __ix;
00308 if (__mask & __cat)
00309 {
00310
00311 _M_replace_category(__imp, _S_facet_categories[__ix]);
00312
00313 if (strcmp(_M_names[__ix], "*") != 0
00314 && strcmp(__imp->_M_names[__ix], "*") != 0)
00315 {
00316 delete [] _M_names[__ix];
00317 char* __new = new char[strlen(__imp->_M_names[__ix]) + 1];
00318 strcpy(__new, __imp->_M_names[__ix]);
00319 _M_names[__ix] = __new;
00320 }
00321 }
00322 }
00323 }
00324
00325 void
00326 locale::_Impl::
00327 _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
00328 {
00329 for (; *__idpp; ++__idpp)
00330 _M_replace_facet(__imp, *__idpp);
00331 }
00332
00333 void
00334 locale::_Impl::
00335 _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
00336 {
00337 size_t __index = __idp->_M_id();
00338 if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index])
00339 __throw_runtime_error("no locale facet");
00340 _M_install_facet(__idp, __imp->_M_facets[__index]);
00341 }
00342
00343 void
00344 locale::_Impl::
00345 _M_install_facet(const locale::id* __idp, facet* __fp)
00346 {
00347 if (__fp)
00348 {
00349 size_t __index = __idp->_M_id();
00350
00351
00352 if (__index > _M_facets_size - 1)
00353 {
00354 facet** __old = _M_facets;
00355 facet** __new;
00356 const size_t __new_size = __index + 4;
00357 __new = new facet*[2 * __new_size];
00358 for (size_t __i = 0; __i < _M_facets_size; ++__i)
00359 __new[__i] = _M_facets[__i];
00360 for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
00361 __new[__i2] = 0;
00362
00363 for (size_t __i = 0; __i < _M_facets_size; ++__i)
00364 __new[__i + __new_size] = _M_facets[__i + _M_facets_size];
00365 for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
00366 __new[__i2 + __new_size] = 0;
00367
00368 _M_facets_size = __new_size;
00369 _M_facets = __new;
00370 delete [] __old;
00371 }
00372
00373 __fp->_M_add_reference();
00374 facet*& __fpr = _M_facets[__index];
00375 if (__fpr)
00376 {
00377
00378 __fpr->_M_remove_reference();
00379 __fpr = __fp;
00380 }
00381 else
00382 {
00383
00384
00385
00386 _M_facets[__index] = __fp;
00387 }
00388 }
00389 }
00390 }