~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/common/xlocale.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/common/xlocale.cpp
 
3
// Purpose:     xlocale wrappers/impl to provide some xlocale wrappers
 
4
// Author:      Brian Vanderburg II, Vadim Zeitlin
 
5
// Created:     2008-01-07
 
6
// Copyright:   (c) 2008 Brian Vanderburg II
 
7
//                  2008 Vadim Zeitlin <vadim@wxwidgets.org>
 
8
// Licence:     wxWindows licence
 
9
///////////////////////////////////////////////////////////////////////////////
 
10
 
 
11
// ============================================================================
 
12
// declarations
 
13
// ============================================================================
 
14
 
 
15
// ----------------------------------------------------------------------------
 
16
// headers
 
17
// ----------------------------------------------------------------------------
 
18
 
 
19
#include "wx/wxprec.h"
 
20
 
 
21
#ifdef __BORLANDC__
 
22
    #pragma hdrstop
 
23
#endif
 
24
 
 
25
#if wxUSE_XLOCALE
 
26
 
 
27
#ifndef WX_PRECOMP
 
28
    #include "wx/module.h"
 
29
#endif
 
30
 
 
31
#include "wx/xlocale.h"
 
32
 
 
33
#include <errno.h>
 
34
#include <locale.h>
 
35
 
 
36
// ----------------------------------------------------------------------------
 
37
// module globals
 
38
// ----------------------------------------------------------------------------
 
39
 
 
40
// This is the C locale object, it is created on demand
 
41
static wxXLocale *gs_cLocale = NULL;
 
42
 
 
43
wxXLocale wxNullXLocale;
 
44
 
 
45
 
 
46
// ============================================================================
 
47
// implementation
 
48
// ============================================================================
 
49
 
 
50
// ----------------------------------------------------------------------------
 
51
// Module for gs_cLocale cleanup
 
52
// ----------------------------------------------------------------------------
 
53
 
 
54
class wxXLocaleModule : public wxModule
 
55
{
 
56
public:
 
57
    virtual bool OnInit() { return true; }
 
58
    virtual void OnExit() { wxDELETE(gs_cLocale); }
 
59
 
 
60
    DECLARE_DYNAMIC_CLASS(wxXLocaleModule)
 
61
};
 
62
 
 
63
IMPLEMENT_DYNAMIC_CLASS(wxXLocaleModule, wxModule)
 
64
 
 
65
 
 
66
// ============================================================================
 
67
// wxXLocale implementation
 
68
// ============================================================================
 
69
 
 
70
// ----------------------------------------------------------------------------
 
71
// common parts
 
72
// ----------------------------------------------------------------------------
 
73
 
 
74
// Get the C locale
 
75
wxXLocale& wxXLocale::GetCLocale()
 
76
{
 
77
    if ( !gs_cLocale )
 
78
    {
 
79
        // NOTE: bcc551 has trouble doing static_cast with incomplete
 
80
        //       type definition. reinterpret_cast used as workaround
 
81
        gs_cLocale = new wxXLocale( reinterpret_cast<wxXLocaleCTag *>(NULL) );
 
82
    }
 
83
 
 
84
    return *gs_cLocale;
 
85
}
 
86
 
 
87
#ifdef wxHAS_XLOCALE_SUPPORT
 
88
 
 
89
wxXLocale::wxXLocale(wxLanguage lang)
 
90
{
 
91
    const wxLanguageInfo * const info = wxLocale::GetLanguageInfo(lang);
 
92
    if ( !info )
 
93
    {
 
94
        m_locale = NULL;
 
95
    }
 
96
    else
 
97
    {
 
98
        Init(info->GetLocaleName().c_str());
 
99
    }
 
100
}
 
101
 
 
102
#if wxCHECK_VISUALC_VERSION(8)
 
103
 
 
104
// ----------------------------------------------------------------------------
 
105
// implementation using MSVC locale API
 
106
// ----------------------------------------------------------------------------
 
107
 
 
108
void wxXLocale::Init(const char *loc)
 
109
{
 
110
    if (!loc || *loc == '\0')
 
111
        return;
 
112
 
 
113
    m_locale = _create_locale(LC_ALL, loc);
 
114
}
 
115
 
 
116
void wxXLocale::Free()
 
117
{
 
118
    if ( m_locale )
 
119
        _free_locale(m_locale);
 
120
}
 
121
 
 
122
#elif defined(HAVE_LOCALE_T)
 
123
 
 
124
// ----------------------------------------------------------------------------
 
125
// implementation using xlocale API
 
126
// ----------------------------------------------------------------------------
 
127
 
 
128
void wxXLocale::Init(const char *loc)
 
129
{
 
130
    if (!loc || *loc == '\0')
 
131
        return;
 
132
 
 
133
    m_locale = newlocale(LC_ALL_MASK, loc, NULL);
 
134
    if (!m_locale)
 
135
    {
 
136
        // NOTE: here we do something similar to what wxSetLocaleTryUTF8() does
 
137
        //       in wxLocale code (but with newlocale() calls instead of wxSetlocale())
 
138
        wxString buf(loc);
 
139
        wxString buf2;
 
140
        buf2 = buf + wxS(".UTF-8");
 
141
        m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
 
142
        if ( !m_locale )
 
143
        {
 
144
            buf2 = buf + wxS(".utf-8");
 
145
            m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
 
146
        }
 
147
        if ( !m_locale )
 
148
        {
 
149
            buf2 = buf + wxS(".UTF8");
 
150
            m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
 
151
        }
 
152
        if ( !m_locale )
 
153
        {
 
154
            buf2 = buf + wxS(".utf8");
 
155
            m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
 
156
        }
 
157
    }
 
158
 
 
159
    // TODO: wxLocale performs many more manipulations of the given locale
 
160
    //       string in the attempt to set a valid locale; reusing that code
 
161
    //       (changing it to take a generic wxTryLocale callback) would be nice
 
162
}
 
163
 
 
164
void wxXLocale::Free()
 
165
{
 
166
    if ( m_locale )
 
167
        freelocale(m_locale);
 
168
}
 
169
 
 
170
#else
 
171
    #error "Unknown xlocale support."
 
172
#endif
 
173
 
 
174
#endif // wxHAS_XLOCALE_SUPPORT
 
175
 
 
176
#ifndef wxHAS_XLOCALE_SUPPORT
 
177
 
 
178
// ============================================================================
 
179
// Implementation of wxFoo_l() functions for "C" locale without xlocale support
 
180
// ============================================================================
 
181
 
 
182
// ----------------------------------------------------------------------------
 
183
// character classification and transformation functions
 
184
// ----------------------------------------------------------------------------
 
185
 
 
186
// lookup table and macros for character type functions
 
187
#define CTYPE_ALNUM 0x0001
 
188
#define CTYPE_ALPHA 0x0002
 
189
#define CTYPE_CNTRL 0x0004
 
190
#define CTYPE_DIGIT 0x0008
 
191
#define CTYPE_GRAPH 0x0010
 
192
#define CTYPE_LOWER 0x0020
 
193
#define CTYPE_PRINT 0x0040
 
194
#define CTYPE_PUNCT 0x0080
 
195
#define CTYPE_SPACE 0x0100
 
196
#define CTYPE_UPPER 0x0200
 
197
#define CTYPE_XDIGIT 0x0400
 
198
 
 
199
static const unsigned int gs_lookup[] =
 
200
{
 
201
    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
 
202
    0x0004, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0004, 0x0004,
 
203
    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
 
204
    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
 
205
    0x0140, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
 
206
    0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
 
207
    0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459,
 
208
    0x0459, 0x0459, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
 
209
    0x00D0, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0253,
 
210
    0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
 
211
    0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
 
212
    0x0253, 0x0253, 0x0253, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
 
213
    0x00D0, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0073,
 
214
    0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
 
215
    0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
 
216
    0x0073, 0x0073, 0x0073, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x0004
 
217
};
 
218
 
 
219
 
 
220
#define CTYPE_TEST(c, t) ( (c) <= 127 && (gs_lookup[(c)] & (t)) )
 
221
 
 
222
 
 
223
// ctype functions
 
224
#define GEN_ISFUNC(name, test) \
 
225
int name(const wxUniChar& c, const wxXLocale& loc) \
 
226
{ \
 
227
    wxCHECK(loc.IsOk(), false); \
 
228
    return CTYPE_TEST(c.GetValue(), test); \
 
229
}
 
230
 
 
231
GEN_ISFUNC(wxIsalnum_l, CTYPE_ALNUM)
 
232
GEN_ISFUNC(wxIsalpha_l, CTYPE_ALPHA)
 
233
GEN_ISFUNC(wxIscntrl_l, CTYPE_CNTRL)
 
234
GEN_ISFUNC(wxIsdigit_l, CTYPE_DIGIT)
 
235
GEN_ISFUNC(wxIsgraph_l, CTYPE_GRAPH)
 
236
GEN_ISFUNC(wxIslower_l, CTYPE_LOWER)
 
237
GEN_ISFUNC(wxIsprint_l, CTYPE_PRINT)
 
238
GEN_ISFUNC(wxIspunct_l, CTYPE_PUNCT)
 
239
GEN_ISFUNC(wxIsspace_l, CTYPE_SPACE)
 
240
GEN_ISFUNC(wxIsupper_l, CTYPE_UPPER)
 
241
GEN_ISFUNC(wxIsxdigit_l, CTYPE_XDIGIT)
 
242
 
 
243
int wxTolower_l(const wxUniChar& c, const wxXLocale& loc)
 
244
{
 
245
    wxCHECK(loc.IsOk(), false);
 
246
 
 
247
    if(CTYPE_TEST(c.GetValue(), CTYPE_UPPER))
 
248
    {
 
249
        return c - 'A' + 'a';
 
250
    }
 
251
 
 
252
    return c;
 
253
}
 
254
 
 
255
int wxToupper_l(const wxUniChar& c, const wxXLocale& loc)
 
256
{
 
257
    wxCHECK(loc.IsOk(), false);
 
258
 
 
259
    if(CTYPE_TEST(c.GetValue(), CTYPE_LOWER))
 
260
    {
 
261
        return c - 'a' + 'A';
 
262
    }
 
263
 
 
264
    return c;
 
265
}
 
266
 
 
267
 
 
268
// ----------------------------------------------------------------------------
 
269
// string --> number conversion functions
 
270
// ----------------------------------------------------------------------------
 
271
 
 
272
/*
 
273
    WARNING: the implementation of the wxStrtoX_l() functions below is unsafe
 
274
             in a multi-threaded environment as we temporary change the locale
 
275
             and if in the meanwhile an other thread performs some locale-dependent
 
276
             operation, it may get unexpected results...
 
277
             However this is the best we can do without reinventing the wheel in the
 
278
             case !wxHAS_XLOCALE_SUPPORT...
 
279
*/
 
280
 
 
281
namespace
 
282
{
 
283
 
 
284
// Helper class that changes LC_NUMERIC facet of the global locale in its ctor
 
285
// to "C" locale and restores it in its dtor later.
 
286
class CNumericLocaleSetter
 
287
{
 
288
public:
 
289
    CNumericLocaleSetter()
 
290
        : m_oldLocale(wxStrdupA(setlocale(LC_NUMERIC, NULL)))
 
291
    {
 
292
        if ( !wxSetlocale(LC_NUMERIC, "C") )
 
293
        {
 
294
            // Setting locale to "C" should really always work.
 
295
            wxFAIL_MSG( wxS("Couldn't set LC_NUMERIC to \"C\"") );
 
296
        }
 
297
    }
 
298
 
 
299
    ~CNumericLocaleSetter()
 
300
    {
 
301
        wxSetlocale(LC_NUMERIC, m_oldLocale);
 
302
        free(m_oldLocale);
 
303
    }
 
304
 
 
305
private:
 
306
    char * const m_oldLocale;
 
307
 
 
308
    wxDECLARE_NO_COPY_CLASS(CNumericLocaleSetter);
 
309
};
 
310
 
 
311
} // anonymous namespace
 
312
 
 
313
double wxStrtod_l(const wchar_t* str, wchar_t **endptr, const wxXLocale& loc)
 
314
{
 
315
    wxCHECK( loc.IsOk(), 0. );
 
316
 
 
317
    CNumericLocaleSetter locSetter;
 
318
 
 
319
    return wxStrtod(str, endptr);
 
320
}
 
321
 
 
322
double wxStrtod_l(const char* str, char **endptr, const wxXLocale& loc)
 
323
{
 
324
    wxCHECK( loc.IsOk(), 0. );
 
325
 
 
326
    CNumericLocaleSetter locSetter;
 
327
 
 
328
    return wxStrtod(str, endptr);
 
329
}
 
330
 
 
331
long wxStrtol_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc)
 
332
{
 
333
    wxCHECK( loc.IsOk(), 0 );
 
334
 
 
335
    CNumericLocaleSetter locSetter;
 
336
 
 
337
    return wxStrtol(str, endptr, base);
 
338
}
 
339
 
 
340
long wxStrtol_l(const char* str, char **endptr, int base, const wxXLocale& loc)
 
341
{
 
342
    wxCHECK( loc.IsOk(), 0 );
 
343
 
 
344
    CNumericLocaleSetter locSetter;
 
345
 
 
346
    return wxStrtol(str, endptr, base);
 
347
}
 
348
 
 
349
unsigned long wxStrtoul_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc)
 
350
{
 
351
    wxCHECK( loc.IsOk(), 0 );
 
352
 
 
353
    CNumericLocaleSetter locSetter;
 
354
 
 
355
    return wxStrtoul(str, endptr, base);
 
356
}
 
357
 
 
358
unsigned long wxStrtoul_l(const char* str, char **endptr, int base, const wxXLocale& loc)
 
359
{
 
360
    wxCHECK( loc.IsOk(), 0 );
 
361
 
 
362
    CNumericLocaleSetter locSetter;
 
363
 
 
364
    return wxStrtoul(str, endptr, base);
 
365
}
 
366
 
 
367
#endif // !defined(wxHAS_XLOCALE_SUPPORT)
 
368
 
 
369
#endif // wxUSE_XLOCALE