From 1e50d914af93e769828bac5895622ebdece469c6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Wed, 2 May 2007 09:03:03 +0000 Subject: [PATCH] made wxConvXXX objects usable at static initialization time git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45751 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/strconv.h | 34 +++++++++++--- src/common/strconv.cpp | 100 ++++++++++++++++++++++++++--------------- 2 files changed, 93 insertions(+), 41 deletions(-) diff --git a/include/wx/strconv.h b/include/wx/strconv.h index c25a05017c..b9ea52f68e 100644 --- a/include/wx/strconv.h +++ b/include/wx/strconv.h @@ -418,14 +418,35 @@ private: // declare predefined conversion objects // ---------------------------------------------------------------------------- +// Note: this macro is an implementation detail (see the comment in +// strconv.cpp). The wxGet_XXX() and wxGet_XXXPtr() functions shouldn't be +// used by user code and neither should XXXPtr, use the wxConvXXX macro +// instead. +#define WX_DECLARE_GLOBAL_CONV(klass, name) \ + extern WXDLLIMPEXP_DATA_BASE(klass*) name##Ptr; \ + extern klass* WXDLLIMPEXP_BASE wxGet_##name##Ptr(); \ + inline klass& wxGet_##name() \ + { \ + if ( !name##Ptr ) \ + name##Ptr = wxGet_##name##Ptr(); \ + return *name##Ptr; \ + } + + // conversion to be used with all standard functions affected by locale, e.g. // strtol(), strftime(), ... -extern WXDLLIMPEXP_DATA_BASE(wxMBConv&) wxConvLibc; +WX_DECLARE_GLOBAL_CONV(wxMBConv, wxConvLibc) +#define wxConvLibc wxGet_wxConvLibc() // conversion ISO-8859-1/UTF-7/UTF-8 <-> wchar_t -extern WXDLLIMPEXP_DATA_BASE(wxCSConv&) wxConvISO8859_1; -extern WXDLLIMPEXP_DATA_BASE(wxMBConvUTF7&) wxConvUTF7; -extern WXDLLIMPEXP_DATA_BASE(wxMBConvUTF8&) wxConvUTF8; +WX_DECLARE_GLOBAL_CONV(wxCSConv, wxConvISO8859_1) +#define wxConvISO8859_1 wxGet_wxConvISO8859_1() + +WX_DECLARE_GLOBAL_CONV(wxMBConvUTF8, wxConvUTF8) +#define wxConvUTF8 wxGet_wxConvUTF8() + +WX_DECLARE_GLOBAL_CONV(wxMBConvUTF7, wxConvUTF7) +#define wxConvUTF7 wxGet_wxConvUTF7() // conversion used for the file names on the systems where they're not Unicode // (basically anything except Windows) @@ -444,7 +465,8 @@ extern WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvFileName; extern WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvCurrent; // the conversion corresponding to the current locale -extern WXDLLIMPEXP_DATA_BASE(wxCSConv&) wxConvLocal; +WX_DECLARE_GLOBAL_CONV(wxCSConv, wxConvLocal) +#define wxConvLocal wxGet_wxConvLocal() // the conversion corresponding to the encoding of the standard UI elements // @@ -452,6 +474,8 @@ extern WXDLLIMPEXP_DATA_BASE(wxCSConv&) wxConvLocal; // needs to use a fixed encoding extern WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvUI; +#undef WX_DECLARE_GLOBAL_CONV + // ---------------------------------------------------------------------------- // endianness-dependent conversions // ---------------------------------------------------------------------------- diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 4aaf0ab3b7..f2947edfd3 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -3616,42 +3616,6 @@ size_t wxCSConv::GetMBNulLen() const return 1; } -// ---------------------------------------------------------------------------- -// globals -// ---------------------------------------------------------------------------- - -#ifdef __WINDOWS__ - static wxMBConv_win32 wxConvLibcObj; -#elif defined(__WXMAC__) && !defined(__MACH__) - static wxMBConv_mac wxConvLibcObj ; -#else - static wxMBConvLibc wxConvLibcObj; -#endif - -static wxCSConv wxConvLocalObj(wxFONTENCODING_SYSTEM); -static wxCSConv wxConvISO8859_1Obj(wxFONTENCODING_ISO8859_1); -static wxMBConvUTF7 wxConvUTF7Obj; -static wxMBConvUTF8 wxConvUTF8Obj; -#if defined(__WXMAC__) && defined(TARGET_CARBON) -static wxMBConv_macUTF8D wxConvMacUTF8DObj; -#endif -WXDLLIMPEXP_DATA_BASE(wxMBConv&) wxConvLibc = wxConvLibcObj; -WXDLLIMPEXP_DATA_BASE(wxCSConv&) wxConvLocal = wxConvLocalObj; -WXDLLIMPEXP_DATA_BASE(wxCSConv&) wxConvISO8859_1 = wxConvISO8859_1Obj; -WXDLLIMPEXP_DATA_BASE(wxMBConvUTF7&) wxConvUTF7 = wxConvUTF7Obj; -WXDLLIMPEXP_DATA_BASE(wxMBConvUTF8&) wxConvUTF8 = wxConvUTF8Obj; -WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvCurrent = &wxConvLibcObj; -WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvUI = &wxConvLocal; -WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvFileName = & -#ifdef __WXOSX__ -#if defined(__WXMAC__) && defined(TARGET_CARBON) - wxConvMacUTF8DObj; -#else - wxConvUTF8Obj; -#endif -#else // !__WXOSX__ - wxConvLibcObj; -#endif // __WXOSX__/!__WXOSX__ #if wxUSE_UNICODE @@ -3683,8 +3647,72 @@ wxCharBuffer wxSafeConvertWX2MB(const wchar_t *ws) #endif // wxUSE_UNICODE +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- + +// NB: The reason why we create converted objects in this convoluted way, +// using a factory function instead of global variable, is that they +// may be used at static initialization time (some of them are used by +// wxString ctors and there may be a global wxString object). In other +// words, possibly _before_ the converter global object would be +// initialized. + +#undef wxConvLibc +#undef wxConvUTF8 +#undef wxConvUTF7 +#undef wxConvLocal +#undef wxConvISO8859_1 + +#define WX_DEFINE_GLOBAL_CONV2(klass, impl_klass, name, ctor_args) \ + WXDLLIMPEXP_DATA_BASE(klass*) name##Ptr = NULL; \ + klass* WXDLLIMPEXP_BASE wxGet_##name##Ptr() \ + { \ + static impl_klass name##Obj ctor_args; \ + return &name##Obj; \ + } \ + /* this ensures that all global converter objects are created */ \ + /* by the time static initialization is done, i.e. before any */ \ + /* thread is launched: */ \ + static klass* gs_##name##instance = wxGet_##name##Ptr() + +#define WX_DEFINE_GLOBAL_CONV(klass, name, ctor_args) \ + WX_DEFINE_GLOBAL_CONV2(klass, klass, name, ctor_args) + +#ifdef __WINDOWS__ + WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConv_win32, wxConvLibc, wxEMPTY_PARAMETER_VALUE); +#elif defined(__WXMAC__) && !defined(__MACH__) + WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConv_mac, wxConvLibc, wxEMPTY_PARAMETER_VALUE); +#else + WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConvLibc, wxConvLibc, wxEMPTY_PARAMETER_VALUE); +#endif + +WX_DEFINE_GLOBAL_CONV(wxMBConvUTF8, wxConvUTF8, wxEMPTY_PARAMETER_VALUE); +WX_DEFINE_GLOBAL_CONV(wxMBConvUTF7, wxConvUTF7, wxEMPTY_PARAMETER_VALUE); + +WX_DEFINE_GLOBAL_CONV(wxCSConv, wxConvLocal, (wxFONTENCODING_SYSTEM)); +WX_DEFINE_GLOBAL_CONV(wxCSConv, wxConvISO8859_1, (wxFONTENCODING_ISO8859_1)); + +WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvCurrent = wxGet_wxConvLibcPtr(); +WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvUI = wxGet_wxConvLocalPtr(); + +#if defined(__WXMAC__) && defined(TARGET_CARBON) +static wxMBConv_macUTF8D wxConvMacUTF8DObj; +#endif +WXDLLIMPEXP_DATA_BASE(wxMBConv *) wxConvFileName = +#ifdef __WXOSX__ +#if defined(__WXMAC__) && defined(TARGET_CARBON) + &wxConvMacUTF8DObj; +#else + wxGet_wxConvUTF8Ptr(); +#endif +#else // !__WXOSX__ + wxGet_wxConvLibcPtr(); +#endif // __WXOSX__/!__WXOSX__ + #else // !wxUSE_WCHAR_T +// FIXME-UTF8: remove this, wxUSE_WCHAR_T is required now // stand-ins in absence of wchar_t WXDLLIMPEXP_DATA_BASE(wxMBConv) wxConvLibc, wxConvISO8859_1, -- 2.47.2