Instrument Neutral Distributed Interface INDI  2.0.2
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
27 extern "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 
44 typedef 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 
62 typedef char locale_char_t;
63 #define INDI_LOCALE(s) s
64 
65 inline static locale_char_t *indi_setlocale(int category, const locale_char_t *locale)
66 {
67  return setlocale(category, locale);
68 }
69 
70 inline 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 
105 class 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 
135 class AutoCNumeric : public AutoLocale
136 {
137  public:
138  AutoCNumeric() : AutoLocale(LC_NUMERIC, INDI_LOCALE("C")) { }
139 };
140 
141 #endif // __cplusplus
#define _INDI_C_INLINE
Definition: locale_compat.h:75
#define INDI_LOCALE(s)
Definition: locale_compat.h:63
char locale_char_t
Definition: locale_compat.h:62