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