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