Instrument Neutral Distributed Interface INDI 2.2.5
locale_compat.h
Go to the documentation of this file.
1/*
2 INDI LIB
3 Utility routines for saving and restoring the current locale, handling platform differences
4 Copyright (C) 2017 Andy Galasso
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20*/
21
22#pragma once
23
24#include <locale.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30// C interface
31//
32// usage:
33//
34// locale_char_t *save = indi_locale_C_numeric_push();
35// ...
36// indi_locale_C_numeric_pop(save);
37//
38
39#if defined(_MSC_VER)
40
41#include <string.h>
42#include <malloc.h>
43
44typedef wchar_t locale_char_t;
45#define INDI_LOCALE(s) L""#s
46
47__inline static locale_char_t *indi_setlocale(int category, const locale_char_t *locale)
48{
49 return _wcsdup(_wsetlocale(category, locale));
50}
51
52__inline static void indi_restore_locale(int category, locale_char_t *prev)
53{
54 _wsetlocale(category, prev);
55 free(prev);
56}
57
58# define _INDI_C_INLINE __inline
59
60#else // _MSC_VER
61
62typedef char locale_char_t;
63#define INDI_LOCALE(s) s
64
65inline static locale_char_t *indi_setlocale(int category, const locale_char_t *locale)
66{
67 return setlocale(category, locale);
68}
69
70inline static void indi_restore_locale(int category, locale_char_t *prev)
71{
72 setlocale(category, prev);
73}
74
75# define _INDI_C_INLINE inline
76
77#endif // _MSC_VER
78
79_INDI_C_INLINE static locale_char_t *indi_locale_C_numeric_push()
80{
81 return indi_setlocale(LC_NUMERIC, INDI_LOCALE("C"));
82}
83
84_INDI_C_INLINE static void indi_locale_C_numeric_pop(locale_char_t *prev)
85{
86 indi_restore_locale(LC_NUMERIC, prev);
87}
88
89#undef _INDI_C_INLINE
90
91#ifdef __cplusplus
92}
93#endif
94
95#ifdef __cplusplus
96
97// C++ interface
98//
99// usage:
100//
101// AutoCNumeric locale; // LC_NUMERIC locale set to "C" for object scope
102// ...
103//
104
105class AutoLocale
106{
107 int m_category;
108 locale_char_t *m_orig;
109
110 public:
111
112 AutoLocale(int category, const locale_char_t *locale)
113 : m_category(category)
114 {
115 m_orig = indi_setlocale(category, locale);
116 }
117
118 // method Restore can be used to restore the original locale
119 // before the object goes out of scope
120 void Restore()
121 {
122 if (m_orig)
123 {
124 indi_restore_locale(m_category, m_orig);
125 m_orig = nullptr;
126 }
127 }
128
129 ~AutoLocale()
130 {
131 Restore();
132 }
133};
134
135class AutoCNumeric : public AutoLocale
136{
137 public:
138 AutoCNumeric() : AutoLocale(LC_NUMERIC, INDI_LOCALE("C")) { }
139};
140
141#endif // __cplusplus
#define _INDI_C_INLINE
#define INDI_LOCALE(s)
char locale_char_t