1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrAutoLocaleSetter_DEFINED 9 #define GrAutoLocaleSetter_DEFINED 10 11 #include "GrTypes.h" 12 13 #if defined(SK_BUILD_FOR_WIN) 14 #include "SkString.h" 15 #endif 16 17 #if !defined(SK_BUILD_FOR_ANDROID) 18 #include <locale.h> 19 #endif 20 21 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 22 #include <xlocale.h> 23 #define HAVE_XLOCALE 1 24 #else 25 #define HAVE_XLOCALE 0 26 #endif 27 28 #if defined(SK_BUILD_FOR_ANDROID) || defined(__UCLIBC__) || defined(_NEWLIB_VERSION) 29 #define HAVE_LOCALE_T 0 30 #else 31 #define HAVE_LOCALE_T 1 32 #endif 33 34 /** 35 * Helper class for ensuring that we don't use the wrong locale when building shaders. Android 36 * doesn't support locale in the NDK, so this is a no-op there. 37 */ 38 class GrAutoLocaleSetter : public SkNoncopyable { 39 public: 40 GrAutoLocaleSetter (const char* name) { 41 #if defined(SK_BUILD_FOR_WIN) 42 fOldPerThreadLocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); 43 char* oldLocale = setlocale(LC_ALL, name); 44 if (oldLocale) { 45 fOldLocale = oldLocale; 46 fShouldRestoreLocale = true; 47 } else { 48 fShouldRestoreLocale = false; 49 } 50 #elif HAVE_LOCALE_T 51 #if HAVE_XLOCALE 52 // In xlocale nullptr means the C locale. 53 if (0 == strcmp(name, "C")) { 54 name = nullptr; 55 } 56 #endif 57 fLocale = newlocale(LC_ALL_MASK, name, nullptr); 58 if (fLocale) { 59 fOldLocale = uselocale(fLocale); 60 } else { 61 fOldLocale = static_cast<locale_t>(nullptr); 62 } 63 #else 64 (void) name; // suppress unused param warning. 65 #endif 66 } 67 68 ~GrAutoLocaleSetter () { 69 #if defined(SK_BUILD_FOR_WIN) 70 if (fShouldRestoreLocale) { 71 setlocale(LC_ALL, fOldLocale.c_str()); 72 } 73 _configthreadlocale(fOldPerThreadLocale); 74 #elif HAVE_LOCALE_T 75 if (fLocale) { 76 uselocale(fOldLocale); 77 freelocale(fLocale); 78 } 79 #endif 80 } 81 82 private: 83 #if defined(SK_BUILD_FOR_WIN) 84 int fOldPerThreadLocale; 85 bool fShouldRestoreLocale; 86 SkString fOldLocale; 87 #elif HAVE_LOCALE_T 88 locale_t fOldLocale; 89 locale_t fLocale; 90 #endif 91 }; 92 93 #undef HAVE_LOCALE_T 94 #undef HAVE_XLOCALE 95 96 #endif 97