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