| /* | |
| * Copyright 2015 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef GrAutoLocaleSetter_DEFINED | |
| #define GrAutoLocaleSetter_DEFINED | |
| #include "include/core/SkTypes.h" | |
| #include "include/private/base/SkNoncopyable.h" | |
| #if defined(SK_BUILD_FOR_WIN) | |
| #include "include/core/SkString.h" | |
| #endif | |
| #if !defined(SK_BUILD_FOR_ANDROID) | |
| #include <locale.h> | |
| #endif | |
| #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | |
| #include <xlocale.h> | |
| #include <cstring> | |
| #define HAVE_XLOCALE 1 | |
| #else | |
| #define HAVE_XLOCALE 0 | |
| #endif | |
| #if defined(SK_BUILD_FOR_ANDROID) || defined(__UCLIBC__) || defined(_NEWLIB_VERSION) | |
| #define HAVE_LOCALE_T 0 | |
| #else | |
| #define HAVE_LOCALE_T 1 | |
| #endif | |
| /** | |
| * Helper class for ensuring that we don't use the wrong locale when building shaders. Android | |
| * doesn't support locale in the NDK, so this is a no-op there. | |
| */ | |
| class GrAutoLocaleSetter : public SkNoncopyable { | |
| public: | |
| GrAutoLocaleSetter (const char* name) { | |
| #if defined(SK_BUILD_FOR_WIN) | |
| fOldPerThreadLocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); | |
| char* oldLocale = setlocale(LC_ALL, name); | |
| if (oldLocale) { | |
| fOldLocale = oldLocale; | |
| fShouldRestoreLocale = true; | |
| } else { | |
| fShouldRestoreLocale = false; | |
| } | |
| #elif HAVE_LOCALE_T | |
| #if HAVE_XLOCALE | |
| // In xlocale nullptr means the C locale. | |
| if (0 == strcmp(name, "C")) { | |
| name = nullptr; | |
| } | |
| #endif | |
| fLocale = newlocale(LC_ALL_MASK, name, nullptr); | |
| if (fLocale) { | |
| fOldLocale = uselocale(fLocale); | |
| } else { | |
| fOldLocale = static_cast<locale_t>(nullptr); | |
| } | |
| #else | |
| (void) name; // suppress unused param warning. | |
| #endif | |
| } | |
| ~GrAutoLocaleSetter () { | |
| #if defined(SK_BUILD_FOR_WIN) | |
| if (fShouldRestoreLocale) { | |
| setlocale(LC_ALL, fOldLocale.c_str()); | |
| } | |
| _configthreadlocale(fOldPerThreadLocale); | |
| #elif HAVE_LOCALE_T | |
| if (fLocale) { | |
| uselocale(fOldLocale); | |
| freelocale(fLocale); | |
| } | |
| #endif | |
| } | |
| private: | |
| #if defined(SK_BUILD_FOR_WIN) | |
| int fOldPerThreadLocale; | |
| bool fShouldRestoreLocale; | |
| SkString fOldLocale; | |
| #elif HAVE_LOCALE_T | |
| locale_t fOldLocale; | |
| locale_t fLocale; | |
| #endif | |
| }; | |
| #undef HAVE_LOCALE_T | |
| #undef HAVE_XLOCALE | |
| #endif |