Replace wxLocale::ms_languagesDB dynamic array with a wxVector

There is no reason to use the macro-based classes for this array as
there are no compatibility constraints here, so use a simple vector
instead.

Note that we need an extra boolean variable now that we don't use a
pointer because we can't just check whether the vector is empty, as this
would return in infinite recursion when InitLanguagesDB() calls
AddLanguage() which, in turn, calls CreateLanguagesDB().
This commit is contained in:
Vadim Zeitlin
2021-08-31 17:37:13 +02:00
parent 5bf11d94a7
commit e92da29272
2 changed files with 28 additions and 30 deletions

View File

@@ -35,7 +35,6 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLIMPEXP_FWD_BASE wxLocale; class WXDLLIMPEXP_FWD_BASE wxLocale;
class WXDLLIMPEXP_FWD_BASE wxLanguageInfoArray;
// ============================================================================ // ============================================================================
// locale support // locale support
@@ -285,8 +284,6 @@ private:
wxTranslations m_translations; wxTranslations m_translations;
static wxLanguageInfoArray *ms_languagesDB;
wxDECLARE_NO_COPY_CLASS(wxLocale); wxDECLARE_NO_COPY_CLASS(wxLocale);
}; };

View File

@@ -24,7 +24,6 @@
#if wxUSE_INTL #if wxUSE_INTL
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/dynarray.h"
#include "wx/string.h" #include "wx/string.h"
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/log.h" #include "wx/log.h"
@@ -52,6 +51,7 @@
#include "wx/stdpaths.h" #include "wx/stdpaths.h"
#include "wx/hashset.h" #include "wx/hashset.h"
#include "wx/uilocale.h" #include "wx/uilocale.h"
#include "wx/vector.h"
#ifdef __WIN32__ #ifdef __WIN32__
#include "wx/msw/private/uilocale.h" #include "wx/msw/private/uilocale.h"
@@ -193,24 +193,26 @@ wxString wxLanguageInfo::GetLocaleName() const
// wxLocale // wxLocale
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "wx/arrimpl.cpp" static wxVector<wxLanguageInfo> gs_languagesDB;
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxLanguageInfo, wxLanguageInfoArray, WXDLLIMPEXP_BASE); static bool gs_languagesDBInitialized = false;
WX_DEFINE_OBJARRAY(wxLanguageInfoArray)
wxLanguageInfoArray *wxLocale::ms_languagesDB = NULL;
/*static*/ void wxLocale::CreateLanguagesDB() /*static*/ void wxLocale::CreateLanguagesDB()
{ {
if (ms_languagesDB == NULL) if (!gs_languagesDBInitialized)
{ {
ms_languagesDB = new wxLanguageInfoArray; gs_languagesDBInitialized = true;
InitLanguagesDB(); InitLanguagesDB();
} }
} }
/*static*/ void wxLocale::DestroyLanguagesDB() /*static*/ void wxLocale::DestroyLanguagesDB()
{ {
wxDELETE(ms_languagesDB); if (gs_languagesDBInitialized)
{
gs_languagesDB.clear();
gs_languagesDBInitialized = false;
}
} }
@@ -476,7 +478,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
// init i to avoid compiler warning // init i to avoid compiler warning
size_t i = 0, size_t i = 0,
count = ms_languagesDB->GetCount(); count = gs_languagesDB.size();
#ifdef __WXOSX__ #ifdef __WXOSX__
wxCFRef<CFLocaleRef> userLocaleRef(CFLocaleCopyCurrent()); wxCFRef<CFLocaleRef> userLocaleRef(CFLocaleCopyCurrent());
@@ -493,7 +495,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
int langOnlyMatchIndex = wxNOT_FOUND; int langOnlyMatchIndex = wxNOT_FOUND;
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
const wxString& fullname = ms_languagesDB->Item(i).CanonicalName; const wxString& fullname = gs_languagesDB[i].CanonicalName;
if ( langFull == fullname ) if ( langFull == fullname )
{ {
// Exact match, no need to look any further. // Exact match, no need to look any further.
@@ -599,7 +601,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
wxString langFullWithModifier = langFull + modifier; wxString langFullWithModifier = langFull + modifier;
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
if ( ms_languagesDB->Item(i).CanonicalName == langFullWithModifier ) if ( gs_languagesDB[i].CanonicalName == langFullWithModifier )
break; break;
} }
} }
@@ -609,7 +611,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
{ {
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
if ( ms_languagesDB->Item(i).CanonicalName == langFull ) if ( gs_languagesDB[i].CanonicalName == langFull )
break; break;
} }
} }
@@ -619,7 +621,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
{ {
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
if ( ExtractLang(ms_languagesDB->Item(i).CanonicalName) == lang ) if ( ExtractLang(gs_languagesDB[i].CanonicalName) == lang )
{ {
break; break;
} }
@@ -631,8 +633,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
{ {
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
if ( ExtractLang(ms_languagesDB->Item(i).CanonicalName) if ( ExtractLang(gs_languagesDB[i].CanonicalName) == langFull )
== langFull )
{ {
break; break;
} }
@@ -648,7 +649,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
// find the name in verbose description. // find the name in verbose description.
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
if (ms_languagesDB->Item(i).Description.CmpNoCase(langFull) == 0) if (gs_languagesDB[i].Description.CmpNoCase(langFull) == 0)
{ {
break; break;
} }
@@ -663,8 +664,8 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
for ( i = 0; i < count; i++ ) for ( i = 0; i < count; i++ )
{ {
if (ms_languagesDB->Item(i).WinLang == lang && if (gs_languagesDB[i].WinLang == lang &&
ms_languagesDB->Item(i).WinSublang == sublang) gs_languagesDB[i].WinSublang == sublang)
{ {
break; break;
} }
@@ -676,7 +677,7 @@ inline bool wxGetNonEmptyEnvVar(const wxString& name, wxString* value)
if ( i < count ) if ( i < count )
{ {
// we did find a matching entry, use it // we did find a matching entry, use it
return ms_languagesDB->Item(i).Language; return gs_languagesDB[i].Language;
} }
// no info about this language in the database // no info about this language in the database
@@ -841,7 +842,7 @@ wxFontEncoding wxLocale::GetSystemEncoding()
void wxLocale::AddLanguage(const wxLanguageInfo& info) void wxLocale::AddLanguage(const wxLanguageInfo& info)
{ {
CreateLanguagesDB(); CreateLanguagesDB();
ms_languagesDB->Add(info); gs_languagesDB.push_back(info);
} }
/* static */ /* static */
@@ -857,11 +858,11 @@ const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang)
if ( lang == wxLANGUAGE_UNKNOWN ) if ( lang == wxLANGUAGE_UNKNOWN )
return NULL; return NULL;
const size_t count = ms_languagesDB->GetCount(); const size_t count = gs_languagesDB.size();
for ( size_t i = 0; i < count; i++ ) for ( size_t i = 0; i < count; i++ )
{ {
if ( ms_languagesDB->Item(i).Language == lang ) if ( gs_languagesDB[i].Language == lang )
return &ms_languagesDB->Item(i); return &gs_languagesDB[i];
} }
return NULL; return NULL;
@@ -904,10 +905,10 @@ const wxLanguageInfo *wxLocale::FindLanguageInfo(const wxString& locale)
const wxLanguageInfo *infoRet = NULL; const wxLanguageInfo *infoRet = NULL;
const size_t count = ms_languagesDB->GetCount(); const size_t count = gs_languagesDB.size();
for ( size_t i = 0; i < count; i++ ) for ( size_t i = 0; i < count; i++ )
{ {
const wxLanguageInfo *info = &ms_languagesDB->Item(i); const wxLanguageInfo *info = &gs_languagesDB[i];
if ( wxStricmp(locale, info->CanonicalName) == 0 || if ( wxStricmp(locale, info->CanonicalName) == 0 ||
wxStricmp(locale, info->Description) == 0 ) wxStricmp(locale, info->Description) == 0 )
@@ -924,7 +925,7 @@ const wxLanguageInfo *wxLocale::FindLanguageInfo(const wxString& locale)
// //
// OTOH, maybe we had already found a language match and in this // OTOH, maybe we had already found a language match and in this
// case don't overwrite it because the entry for the default // case don't overwrite it because the entry for the default
// country always appears first in ms_languagesDB // country always appears first in gs_languagesDB
if ( !infoRet ) if ( !infoRet )
infoRet = info; infoRet = info;
} }