Add wxEnsureLocaleIsCompatibleWithCRT() helper

No real changes, just refactor the code to use this function instead of
calling setlocale(LC_CTYPE) twice.

This makes it more clear what we're doing and will make it simpler to
get rid of this when we don't have to do it any longer.
This commit is contained in:
Vadim Zeitlin 2023-04-22 18:58:16 +02:00
parent 88cf7653fa
commit fcde4ac7c6
3 changed files with 25 additions and 20 deletions

View file

@ -46,4 +46,22 @@ private:
wxDECLARE_NO_COPY_CLASS(wxCLocaleSetter);
};
// This function must be called on program startup and after changing
// locale to ensure LC_CTYPE is set correctly under macOS (it does nothing
// under the other platforms currently).
inline void wxEnsureLocaleIsCompatibleWithCRT()
{
#if defined(__WXOSX__)
// In OS X and iOS, wchar_t CRT functions convert to char* and fail under
// some locales. The safest fix is to set LC_CTYPE to UTF-8 to ensure that
// they can handle any input.
//
// Note that this must be done for any app, Cocoa or console, whether or
// not it uses wxLocale.
//
// See https://stackoverflow.com/questions/11713745/why-does-the-printf-family-of-functions-care-about-locale
setlocale(LC_CTYPE, "UTF-8");
#endif // defined(__WXOSX__)
}
#endif // _WX_PRIVATE_LOCALESET_H_

View file

@ -23,7 +23,6 @@
#include "wx/app.h"
#include "wx/filefn.h"
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/module.h"
#endif
@ -50,9 +49,7 @@
#endif // wxCrtSetDbgFlag
#endif // __WINDOWS__
#if defined(__WXOSX__)
#include <locale.h>
#endif
#include "wx/private/localeset.h"
#include <memory>
@ -217,17 +214,9 @@ static void FreeConvertedArgs()
// initialization which is always done (not customizable) before wxApp creation
static bool DoCommonPreInit()
{
#if defined(__WXOSX__)
// In OS X and iOS, wchar_t CRT functions convert to char* and fail under
// some locales. The safest fix is to set LC_CTYPE to UTF-8 to ensure that
// they can handle any input.
//
// Note that this must be done for any app, Cocoa or console, whether or
// not it uses wxLocale.
//
// See https://stackoverflow.com/questions/11713745/why-does-the-printf-family-of-functions-care-about-locale
setlocale(LC_CTYPE, "UTF-8");
#endif // defined(__WXOSX__)
// This is necessary even for the default locale, see comments in this
// function.
wxEnsureLocaleIsCompatibleWithCRT();
#if wxUSE_LOG
// Reset logging in case we were cleaned up and are being reinitialized.

View file

@ -52,6 +52,7 @@
#include "wx/hashset.h"
#include "wx/uilocale.h"
#include "wx/private/localeset.h"
#include "wx/private/uilocale.h"
#ifdef __WIN32__
@ -396,11 +397,8 @@ bool wxLocale::DoCommonPostInit(bool success,
t->AddStdCatalog();
}
#if defined(__WXOSX__)
// LC_CTYPE is set in DoCommonPreInit() (see init.cpp). Set it again here,
// in case its value was changed/lost during wxLocale initialization.
setlocale(LC_CTYPE, "UTF-8");
#endif // defined(__WXOSX__)
// Do this again here in case LC_CTYPE was changed by setlocale().
wxEnsureLocaleIsCompatibleWithCRT();
return success;
}