diff --git a/common/common.cpp b/common/common.cpp index a7eeb06c26..09a2103716 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -44,6 +44,8 @@ #include #include +#include + /** * Global variables definitions. @@ -58,30 +60,40 @@ EDA_UNITS_T g_UserUnit; EDA_COLOR_T g_GhostColor; -/** - * Function to use local notation or C standard notation for floating point numbers - * some countries use 1,5 and others (and C) 1.5 - * so we switch from local to C and C to local when reading or writing files - * And other problem is a bug when cross compiling under linux: - * a printf print 1,5 and the read functions expects 1.5 - * (depending on version print = 1.5 and read = 1,5 - * Very annoying and we detect this and use a stupid but necessary workaround -*/ -bool g_DisableFloatingPointLocalNotation = false; +/* Class LOCALE_IO + * is a class that can be instantiated within a scope in which you are expecting + * exceptions to be thrown. Its constructor sets a "C" locale, to read/print files + * with fp numbers. + * Its destructor insures that the default locale is restored if an exception + * is thrown, or not. + */ +int LOCALE_IO::m_c_count = 0; -int LOCALE_IO::C_count; - - -void SetLocaleTo_C_standard() +LOCALE_IO::LOCALE_IO() { - setlocale( LC_NUMERIC, "C" ); // Switch the locale to standard C + wxASSERT_MSG( m_c_count >= 0, wxT( "LOCALE_IO::m_c_count mismanaged." ) ); + + // use thread safe, atomic operation + if( __sync_fetch_and_add( &m_c_count, 1 ) == 0 ) + { + // Store the user locale name, to restore this locale later, in dtor + m_user_locale = setlocale( LC_ALL, 0 ); + // Switch the locale to C locale, to read/write files with fp numbers + setlocale( LC_ALL, "C" ); + } } -void SetLocaleTo_Default() +LOCALE_IO::~LOCALE_IO() { - if( !g_DisableFloatingPointLocalNotation ) - setlocale( LC_NUMERIC, "" ); // revert to the current locale + // use thread safe, atomic operation + if( __sync_sub_and_fetch( &m_c_count, 1 ) == 0 ) + { + // revert to the user locale + setlocale( LC_ALL, m_user_locale.c_str() ); + } + + wxASSERT_MSG( m_c_count >= 0, wxT( "LOCALE_IO::m_c_count mismanaged." ) ); } diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index 5dd7d66454..32784f1f21 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -351,6 +351,7 @@ const wxString& PGM_BASE::GetEditorName( bool aCanShowFileChooser ) return m_editor_name; } + const wxString PGM_BASE::AskUserForPreferredEditor( const wxString& aDefaultEditor ) { // Create a mask representing the executable files in the current platform @@ -511,9 +512,6 @@ bool PGM_BASE::initPgm() loadCommonSettings(); - // Set locale option for separator used in float numbers - SetLocaleTo_Default(); - #ifdef __WXMAC__ // Always show filters on Open dialog to be able to choose plugin wxSystemOptions::SetOption( wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, 1 ); @@ -702,20 +700,14 @@ bool PGM_BASE::SetLanguage( bool first_time ) double dtst = 0.5; wxString msg; - extern bool g_DisableFloatingPointLocalNotation; // See common.cpp - - g_DisableFloatingPointLocalNotation = false; - msg << dtst; double result; msg.ToDouble( &result ); - if( result != dtst ) // string to double encode/decode does not work! Bug detected - { + if( result != dtst ) + // string to double encode/decode does not work! Bug detected: // Disable floating point localization: - g_DisableFloatingPointLocalNotation = true; - SetLocaleTo_C_standard( ); - } + setlocale( LC_ALL, "C" ); if( !m_locale->IsLoaded( dictionaryName ) ) m_locale->AddCatalog( dictionaryName ); diff --git a/eeschema/plot_schematic_PDF.cpp b/eeschema/plot_schematic_PDF.cpp index 3640e606b9..fa68f29b5f 100644 --- a/eeschema/plot_schematic_PDF.cpp +++ b/eeschema/plot_schematic_PDF.cpp @@ -66,6 +66,7 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) wxString msg; wxFileName plotFileName; REPORTER& reporter = m_MessagesBox->Reporter(); + LOCALE_IO toggle; // Switch the locale to standard C for( unsigned i = 0; i < sheetList.size(); i++ ) { @@ -94,7 +95,6 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) } // Open the plotter and do the first page - SetLocaleTo_C_standard(); setupPlotPagePDF( plotter, screen ); plotter->StartPlot(); } @@ -134,7 +134,6 @@ void DIALOG_PLOT_SCHEMATIC::restoreEnvironment( PDF_PLOTTER* aPlotter, { aPlotter->EndPlot(); delete aPlotter; - SetLocaleTo_Default(); // Restore the previous sheet m_parent->SetCurrentSheet( aOldsheetpath ); diff --git a/eeschema/plot_schematic_PS.cpp b/eeschema/plot_schematic_PS.cpp index 820ad17dcf..fe5d0713fc 100644 --- a/eeschema/plot_schematic_PS.cpp +++ b/eeschema/plot_schematic_PS.cpp @@ -151,7 +151,8 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetPS( const wxString& aFileName, return false; } - SetLocaleTo_C_standard(); + LOCALE_IO toggle; // Switch the locale to standard C + plotter->StartPlot(); if( aPlotFrameRef ) @@ -168,7 +169,6 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetPS( const wxString& aFileName, plotter->EndPlot(); delete plotter; - SetLocaleTo_Default(); return true; } diff --git a/include/common.h b/include/common.h index b449a5ebaa..97bf56d781 100644 --- a/include/common.h +++ b/include/common.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2014-2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2008-2015 Wayne Stambaugh * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. @@ -181,70 +181,29 @@ extern EDA_UNITS_T g_UserUnit; ///< display units extern EDA_COLOR_T g_GhostColor; -/** - * Function SetLocaleTo_C_standard - * because KiCad is internationalized, switch internalization to "C" standard - * i.e. uses the . (dot) as separator in print/read float numbers - * (some countries (France, Germany ..) use , (comma) as separator) - * This function must be called before read or write ascii files using float - * numbers in data the SetLocaleTo_C_standard function must be called after - * reading or writing the file - * - * This is wrapper to the C setlocale( LC_NUMERIC, "C" ) function, - * but could make more easier an optional use of locale in KiCad - */ -void SetLocaleTo_C_standard(); - -/** - * Function SetLocaleTo_Default - * because KiCad is internationalized, switch internalization to default - * to use the default separator in print/read float numbers - * (. (dot) but some countries (France, Germany ..) use , (comma) as - * separator) - * This function must be called after a call to SetLocaleTo_C_standard - * - * This is wrapper to the C setlocale( LC_NUMERIC, "" ) function, - * but could make more easier an optional use of locale in KiCad - */ -void SetLocaleTo_Default(); - - /** * Class LOCALE_IO * is a class that can be instantiated within a scope in which you are expecting - * exceptions to be thrown. Its constructor calls SetLocaleTo_C_Standard(). + * exceptions to be thrown. Its constructor set a "C" laguage locale option, + * to read/print files with fp numbers. * Its destructor insures that the default locale is restored if an exception * is thrown, or not. */ class LOCALE_IO { public: - LOCALE_IO() - { - wxASSERT_MSG( C_count >= 0, wxT( "LOCALE_IO::C_count mismanaged." ) ); - - // use thread safe, atomic operation - if( __sync_fetch_and_add( &C_count, 1 ) == 0 ) - { - // printf( "setting C locale.\n" ); - SetLocaleTo_C_standard(); - } - } - - ~LOCALE_IO() - { - // use thread safe, atomic operation - if( __sync_sub_and_fetch( &C_count, 1 ) == 0 ) - { - // printf( "restoring default locale.\n" ); - SetLocaleTo_Default(); - } - - wxASSERT_MSG( C_count >= 0, wxT( "LOCALE_IO::C_count mismanaged." ) ); - } + LOCALE_IO(); + ~LOCALE_IO(); private: - static int C_count; // allow for nesting of LOCALE_IO instantiations + void setUserLocale( const char* aUserLocale ); + + // allow for nesting of LOCALE_IO instantiations + static int m_c_count; + + // The locale in use before switching to the "C" locale + // (the locale can be set by user, and is not always the system locale) + std::string m_user_locale; }; diff --git a/include/pgm_base.h b/include/pgm_base.h index 740e5275be..0c6d6c3676 100644 --- a/include/pgm_base.h +++ b/include/pgm_base.h @@ -140,7 +140,7 @@ public: * been set. */ VTBL_ENTRY const wxString& GetEditorName( bool aCanShowFileChooser = true ); - + /** * Shows a dialog that instructs the user to select a new preferred editor. * @param aDefaultEditor Default full path for the default editor this dialog should