KiCad PCB EDA Suite
Loading...
Searching...
No Matches
locale_io.cpp
Go to the documentation of this file.
1
/*
2
* This program source code file is part of KiCad, a free EDA CAD application.
3
*
4
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
*
11
* This program 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
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, you may find one here:
18
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19
* or you may search the http://www.gnu.org website for the version 2 license,
20
* or you may write to the Free Software Foundation, Inc.,
21
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22
*/
23
24
#include <
locale_io.h
>
25
#include <wx/intl.h>
26
#include <clocale>
27
#include <atomic>
28
29
// When reading/writing files, we need to switch to setlocale( LC_NUMERIC, "C" ).
30
// Works fine to read/write files with floating point numbers.
31
// We can call setlocale( LC_NUMERIC, "C" ) or wxLocale( "C", "C", "C", false )
32
// wxWidgets discourage a direct call to setlocale
33
// However, for us, calling wxLocale( "C", "C", "C", false ) has a unwanted effect:
34
// The I18N translations are no longer active, because the English dictionary is selected.
35
// To read files, this is not a major issues, but the result can differ
36
// from using setlocale(xx, "C").
37
// Previously, we used only setlocale( LC_NUMERIC, "C" )
38
//
39
// Known issues are
40
// on MSW
41
// using setlocale( LC_NUMERIC, "C" ) generates an alert message in debug mode,
42
// and this message ("Decimal separator mismatch") must be disabled.
43
// But calling wxLocale( "C", "C", "C", false ) works fine
44
// On unix:
45
// calling wxLocale( "C", "C", "C", false ) breaks env vars containing non ASCII7 chars.
46
// these env vars return a empty string from wxGetEnv() in many cases, and if such a
47
// var must be read after calling wxLocale( "C", "C", "C", false ), it looks like empty
48
//
49
// So use wxLocale on Windows and setlocale on unix
50
51
// On Windows, when using setlocale, a wx alert is generated
52
// in some cases (reading a bitmap for instance)
53
// So we disable alerts during the time a file is read or written
54
55
56
// set USE_WXLOCALE to 0 to use setlocale, 1 to use wxLocale:
57
#if defined( _WIN32 )
58
#define USE_WXLOCALE 1
59
#else
60
#define USE_WXLOCALE 0
61
#endif
62
63
#if !USE_WXLOCALE
64
#if defined( _WIN32 ) && defined( DEBUG )
65
#include <wx/appl.h>
// for wxTheApp
66
67
// a wxAssertHandler_t function to filter wxWidgets alert messages when reading/writing a file
68
// when switching the locale to LC_NUMERIC, "C"
69
// It is used in class LOCALE_IO to hide a useless (in KiCad) wxWidgets alert message
70
void
KiAssertFilter(
const
wxString &file,
int
line,
71
const
wxString &func,
const
wxString &cond,
72
const
wxString &msg)
73
{
74
if
( !msg.Contains(
"Decimal separator mismatch"
) )
75
wxTheApp->OnAssertFailure( file.c_str(), line, func.c_str(), cond.c_str(), msg.c_str() );
76
}
77
#endif
78
#endif
79
80
// allow for nesting of LOCALE_IO instantiations
81
static
std::atomic<unsigned int>
locale_count
( 0 );
82
83
LOCALE_IO::LOCALE_IO
() :
84
m_wxLocale
( nullptr )
85
{
86
// use thread safe, atomic operation
87
if
(
locale_count
++ == 0 )
88
{
89
#if USE_WXLOCALE
90
#define C_LANG "C"
91
m_wxLocale
=
new
wxLocale( C_LANG, C_LANG, C_LANG,
false
);
92
#else
93
// Store the user locale name, to restore this locale later, in dtor
94
m_user_locale
= setlocale( LC_NUMERIC,
nullptr
);
95
#if defined( _WIN32 ) && defined( DEBUG )
96
// Disable wxWidgets alerts
97
wxSetAssertHandler( KiAssertFilter );
98
#endif
99
// Switch the locale to C locale, to read/write files with fp numbers
100
setlocale( LC_NUMERIC,
"C"
);
101
#endif
102
}
103
}
104
105
106
LOCALE_IO::~LOCALE_IO
()
107
{
108
// use thread safe, atomic operation
109
if
( --
locale_count
== 0 )
110
{
111
// revert to the user locale
112
#if USE_WXLOCALE
113
delete
m_wxLocale
;
// Deleting m_wxLocale restored previous locale
114
m_wxLocale
=
nullptr
;
115
#else
116
setlocale( LC_NUMERIC,
m_user_locale
.c_str() );
117
#if defined( _WIN32 ) && defined( DEBUG )
118
// Enable wxWidgets alerts
119
wxSetDefaultAssertHandler();
120
#endif
121
#endif
122
}
123
}
LOCALE_IO::LOCALE_IO
LOCALE_IO()
Definition
locale_io.cpp:83
LOCALE_IO::~LOCALE_IO
~LOCALE_IO()
Definition
locale_io.cpp:106
LOCALE_IO::m_wxLocale
wxLocale * m_wxLocale
Definition
locale_io.h:49
LOCALE_IO::m_user_locale
std::string m_user_locale
Definition
locale_io.h:50
locale_count
static std::atomic< unsigned int > locale_count(0)
locale_io.h
src
common
locale_io.cpp
Generated on Sun Sep 21 2025 01:05:21 for KiCad PCB EDA Suite by
1.13.2