Home | History | Annotate | Download | only in gpu
      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