blob: cec041e086abb2bfbf4167978fcd1cc786b4670b [file] [log] [blame]
bsalomon6f7f2012015-03-16 14:00:52 -07001/*
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
kkinnunenaab16e52015-12-13 23:12:31 -080013#if defined(SK_BUILD_FOR_WIN)
14#include "SkString.h"
15#endif
16
bsalomon6f7f2012015-03-16 14:00:52 -070017#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>
Brian Salomon4d5e65d2017-01-05 10:37:24 -050023#define HAVE_XLOCALE 1
24#else
25#define HAVE_XLOCALE 0
bsalomon6f7f2012015-03-16 14:00:52 -070026#endif
27
smkleindb284c52015-12-15 10:52:51 -080028#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
bsalomon6f7f2012015-03-16 14:00:52 -070034/**
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 */
kkinnunen4222e192015-11-19 08:45:30 -080038class GrAutoLocaleSetter : public SkNoncopyable {
bsalomon6f7f2012015-03-16 14:00:52 -070039public:
40 GrAutoLocaleSetter (const char* name) {
41#if defined(SK_BUILD_FOR_WIN)
halcanary9d524f22016-03-29 09:03:52 -070042 fOldPerThreadLocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
kkinnunenaab16e52015-12-13 23:12:31 -080043 char* oldLocale = setlocale(LC_ALL, name);
44 if (oldLocale) {
45 fOldLocale = oldLocale;
46 fShouldRestoreLocale = true;
47 } else {
48 fShouldRestoreLocale = false;
49 }
smkleindb284c52015-12-15 10:52:51 -080050#elif HAVE_LOCALE_T
Brian Salomon4d5e65d2017-01-05 10:37:24 -050051#if HAVE_XLOCALE
52 // In xlocale nullptr means the C locale.
53 if (0 == strcmp(name, "C")) {
54 name = nullptr;
55 }
56#endif
bsalomon6f7f2012015-03-16 14:00:52 -070057 fLocale = newlocale(LC_ALL, name, 0);
58 if (fLocale) {
59 fOldLocale = uselocale(fLocale);
kkinnunen4222e192015-11-19 08:45:30 -080060 } else {
61 fOldLocale = static_cast<locale_t>(0);
bsalomon6f7f2012015-03-16 14:00:52 -070062 }
63#else
64 (void) name; // suppress unused param warning.
65#endif
66 }
67
68 ~GrAutoLocaleSetter () {
69#if defined(SK_BUILD_FOR_WIN)
kkinnunenaab16e52015-12-13 23:12:31 -080070 if (fShouldRestoreLocale) {
71 setlocale(LC_ALL, fOldLocale.c_str());
bsalomonea750532015-12-04 07:27:36 -080072 }
bsalomon6f7f2012015-03-16 14:00:52 -070073 _configthreadlocale(fOldPerThreadLocale);
smkleindb284c52015-12-15 10:52:51 -080074#elif HAVE_LOCALE_T
bsalomon6f7f2012015-03-16 14:00:52 -070075 if (fLocale) {
76 uselocale(fOldLocale);
77 freelocale(fLocale);
78 }
79#endif
80 }
81
82private:
83#if defined(SK_BUILD_FOR_WIN)
84 int fOldPerThreadLocale;
kkinnunenaab16e52015-12-13 23:12:31 -080085 bool fShouldRestoreLocale;
86 SkString fOldLocale;
smkleindb284c52015-12-15 10:52:51 -080087#elif HAVE_LOCALE_T
bsalomon6f7f2012015-03-16 14:00:52 -070088 locale_t fOldLocale;
89 locale_t fLocale;
90#endif
91};
92
smkleindb284c52015-12-15 10:52:51 -080093#undef HAVE_LOCALE_T
Brian Salomon4d5e65d2017-01-05 10:37:24 -050094#undef HAVE_XLOCALE
smkleindb284c52015-12-15 10:52:51 -080095
bsalomon6f7f2012015-03-16 14:00:52 -070096#endif