|
39 | 39 | _LIBCPP_BEGIN_NAMESPACE_STD |
40 | 40 | namespace __locale { |
41 | 41 |
|
42 | | -struct __locale_guard { |
43 | | - _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __l) : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) { |
44 | | - // Setting the locale can be expensive even when the locale given is |
45 | | - // already the current locale, so do an explicit check to see if the |
46 | | - // current locale is already the one we want. |
47 | | - const char* __lc = __setlocale(nullptr); |
48 | | - // If every category is the same, the locale string will simply be the |
49 | | - // locale name, otherwise it will be a semicolon-separated string listing |
50 | | - // each category. In the second case, we know at least one category won't |
51 | | - // be what we want, so we only have to check the first case. |
52 | | - if (std::strcmp(__l.__get_locale(), __lc) != 0) { |
53 | | - __locale_all = _strdup(__lc); |
54 | | - if (__locale_all == nullptr) |
55 | | - __throw_bad_alloc(); |
56 | | - __setlocale(__l.__get_locale()); |
57 | | - } |
58 | | - } |
59 | | - _LIBCPP_HIDE_FROM_ABI ~__locale_guard() { |
60 | | - // The CRT documentation doesn't explicitly say, but setlocale() does the |
61 | | - // right thing when given a semicolon-separated list of locale settings |
62 | | - // for the different categories in the same format as returned by |
63 | | - // setlocale(LC_ALL, nullptr). |
64 | | - if (__locale_all != nullptr) { |
65 | | - __setlocale(__locale_all); |
66 | | - free(__locale_all); |
67 | | - } |
68 | | - _configthreadlocale(__status); |
69 | | - } |
70 | | - _LIBCPP_HIDE_FROM_ABI static const char* __setlocale(const char* __locale) { |
71 | | - const char* __new_locale = setlocale(LC_ALL, __locale); |
72 | | - if (__new_locale == nullptr) |
73 | | - __throw_bad_alloc(); |
74 | | - return __new_locale; |
75 | | - } |
76 | | - int __status; |
77 | | - char* __locale_all = nullptr; |
78 | | -}; |
79 | | - |
80 | 42 | class __lconv_storage { |
81 | 43 | public: |
82 | 44 | __lconv_storage(const lconv* __lc_input) { |
@@ -322,6 +284,45 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __s |
322 | 284 | _LIBCPP_DIAGNOSTIC_POP |
323 | 285 | #undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT |
324 | 286 |
|
| 287 | +struct __locale_guard { |
| 288 | + _LIBCPP_HIDE_FROM_ABI __locale_guard(__locale_t __l) |
| 289 | + : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) { |
| 290 | + // Setting the locale can be expensive even when the locale given is |
| 291 | + // already the current locale, so do an explicit check to see if the |
| 292 | + // current locale is already the one we want. |
| 293 | + const char* __lc = __setlocale(nullptr); |
| 294 | + // If every category is the same, the locale string will simply be the |
| 295 | + // locale name, otherwise it will be a semicolon-separated string listing |
| 296 | + // each category. In the second case, we know at least one category won't |
| 297 | + // be what we want, so we only have to check the first case. |
| 298 | + if (std::strcmp(__l.__get_locale(), __lc) != 0) { |
| 299 | + __locale_all = _strdup(__lc); |
| 300 | + if (__locale_all == nullptr) |
| 301 | + __throw_bad_alloc(); |
| 302 | + __setlocale(__l.__get_locale()); |
| 303 | + } |
| 304 | + } |
| 305 | + _LIBCPP_HIDE_FROM_ABI ~__locale_guard() { |
| 306 | + // The CRT documentation doesn't explicitly say, but setlocale() does the |
| 307 | + // right thing when given a semicolon-separated list of locale settings |
| 308 | + // for the different categories in the same format as returned by |
| 309 | + // setlocale(LC_ALL, nullptr). |
| 310 | + if (__locale_all != nullptr) { |
| 311 | + __setlocale(__locale_all); |
| 312 | + free(__locale_all); |
| 313 | + } |
| 314 | + _configthreadlocale(__status); |
| 315 | + } |
| 316 | + _LIBCPP_HIDE_FROM_ABI static const char* __setlocale(const char* __locale) { |
| 317 | + const char* __new_locale = setlocale(LC_ALL, __locale); |
| 318 | + if (__new_locale == nullptr) |
| 319 | + __throw_bad_alloc(); |
| 320 | + return __new_locale; |
| 321 | + } |
| 322 | + int __status; |
| 323 | + char* __locale_all = nullptr; |
| 324 | +}; |
| 325 | + |
325 | 326 | } // namespace __locale |
326 | 327 | _LIBCPP_END_NAMESPACE_STD |
327 | 328 |
|
|
0 commit comments