blob: f6a10e5b7d909ca7d5e4c118109b6ffddd5535b0 [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"
Ben Wagnerd5148e32018-07-16 17:44:06 -040012#include "SkNoncopyable.h"
bsalomon6f7f2012015-03-16 14:00:52 -070013
kkinnunenaab16e52015-12-13 23:12:31 -080014#if defined(SK_BUILD_FOR_WIN)
15#include "SkString.h"
16#endif
17
bsalomon6f7f2012015-03-16 14:00:52 -070018#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>
Ben Wagner29f2eaf2018-06-15 13:58:41 -040024#include <cstring>
Brian Salomon4d5e65d2017-01-05 10:37:24 -050025#define HAVE_XLOCALE 1
26#else
27#define HAVE_XLOCALE 0
bsalomon6f7f2012015-03-16 14:00:52 -070028#endif
29
smkleindb284c52015-12-15 10:52:51 -080030#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
bsalomon6f7f2012015-03-16 14:00:52 -070036/**
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 */
kkinnunen4222e192015-11-19 08:45:30 -080040class GrAutoLocaleSetter : public SkNoncopyable {
bsalomon6f7f2012015-03-16 14:00:52 -070041public:
42 GrAutoLocaleSetter (const char* name) {
43#if defined(SK_BUILD_FOR_WIN)
halcanary9d524f22016-03-29 09:03:52 -070044 fOldPerThreadLocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
kkinnunenaab16e52015-12-13 23:12:31 -080045 char* oldLocale = setlocale(LC_ALL, name);
46 if (oldLocale) {
47 fOldLocale = oldLocale;
48 fShouldRestoreLocale = true;
49 } else {
50 fShouldRestoreLocale = false;
51 }
smkleindb284c52015-12-15 10:52:51 -080052#elif HAVE_LOCALE_T
Brian Salomon4d5e65d2017-01-05 10:37:24 -050053#if HAVE_XLOCALE
54 // In xlocale nullptr means the C locale.
55 if (0 == strcmp(name, "C")) {
56 name = nullptr;
57 }
58#endif
Ben Wagnera93a14a2017-08-28 10:34:05 -040059 fLocale = newlocale(LC_ALL_MASK, name, nullptr);
bsalomon6f7f2012015-03-16 14:00:52 -070060 if (fLocale) {
61 fOldLocale = uselocale(fLocale);
kkinnunen4222e192015-11-19 08:45:30 -080062 } else {
Ben Wagnera93a14a2017-08-28 10:34:05 -040063 fOldLocale = static_cast<locale_t>(nullptr);
bsalomon6f7f2012015-03-16 14:00:52 -070064 }
65#else
66 (void) name; // suppress unused param warning.
67#endif
68 }
69
70 ~GrAutoLocaleSetter () {
71#if defined(SK_BUILD_FOR_WIN)
kkinnunenaab16e52015-12-13 23:12:31 -080072 if (fShouldRestoreLocale) {
73 setlocale(LC_ALL, fOldLocale.c_str());
bsalomonea750532015-12-04 07:27:36 -080074 }
bsalomon6f7f2012015-03-16 14:00:52 -070075 _configthreadlocale(fOldPerThreadLocale);
smkleindb284c52015-12-15 10:52:51 -080076#elif HAVE_LOCALE_T
bsalomon6f7f2012015-03-16 14:00:52 -070077 if (fLocale) {
78 uselocale(fOldLocale);
79 freelocale(fLocale);
80 }
81#endif
82 }
83
84private:
85#if defined(SK_BUILD_FOR_WIN)
86 int fOldPerThreadLocale;
kkinnunenaab16e52015-12-13 23:12:31 -080087 bool fShouldRestoreLocale;
88 SkString fOldLocale;
smkleindb284c52015-12-15 10:52:51 -080089#elif HAVE_LOCALE_T
bsalomon6f7f2012015-03-16 14:00:52 -070090 locale_t fOldLocale;
91 locale_t fLocale;
92#endif
93};
94
smkleindb284c52015-12-15 10:52:51 -080095#undef HAVE_LOCALE_T
Brian Salomon4d5e65d2017-01-05 10:37:24 -050096#undef HAVE_XLOCALE
smkleindb284c52015-12-15 10:52:51 -080097
bsalomon6f7f2012015-03-16 14:00:52 -070098#endif