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