Language ID type redeclaration for easier and safer work

This commit is contained in:
Simon Rozman 2016-05-13 10:16:29 +02:00
parent 4e435b044c
commit 710937f8df
7 changed files with 190 additions and 60 deletions

View File

@ -60,6 +60,7 @@ wxEND_EVENT_TABLE()
wxZRColaFrame::wxZRColaFrame() : wxZRColaFrame::wxZRColaFrame() :
m_lang_auto(true), m_lang_auto(true),
m_lang(ZRCola::langid_t_blank),
m_hWndSource(NULL), m_hWndSource(NULL),
m_chrSelect(NULL), m_chrSelect(NULL),
wxZRColaFrameBase(NULL) wxZRColaFrameBase(NULL)
@ -99,7 +100,6 @@ wxZRColaFrame::wxZRColaFrame() :
{ {
// Populate language lists. // Populate language lists.
memcpy(m_lang, ZRCOLA_LANG_VOID, sizeof(m_lang));
ZRColaApp *app = ((ZRColaApp*)wxTheApp); ZRColaApp *app = ((ZRColaApp*)wxTheApp);
m_toolDecompLanguage->Clear(); m_toolDecompLanguage->Clear();
wxString label1_tran(_("Select %s language for decomposition")); wxString label1_tran(_("Select %s language for decomposition"));
@ -111,7 +111,7 @@ wxZRColaFrame::wxZRColaFrame() :
if (i < wxID_DECOMP_LANGUAGE_END - wxID_DECOMP_LANGUAGE_START + 1) if (i < wxID_DECOMP_LANGUAGE_END - wxID_DECOMP_LANGUAGE_START + 1)
m_menuDecompLanguage->AppendRadioItem(wxID_DECOMP_LANGUAGE_START + i, label_tran2, wxString::Format(label1_tran, (const wxStringCharType*)label_tran2)); m_menuDecompLanguage->AppendRadioItem(wxID_DECOMP_LANGUAGE_START + i, label_tran2, wxString::Format(label1_tran, (const wxStringCharType*)label_tran2));
m_toolDecompLanguage->Insert(label_tran2, i); m_toolDecompLanguage->Insert(label_tran2, i);
if (memcmp(m_lang, lang.id, sizeof(m_lang)) == 0) if (m_lang == lang.id)
m_toolDecompLanguage->Select(i); m_toolDecompLanguage->Select(i);
} }
} }
@ -335,7 +335,7 @@ void wxZRColaFrame::OnDecomposedLanguageUpdate(wxUpdateUIEvent& event)
{ {
ZRColaApp *app = ((ZRColaApp*)wxTheApp); ZRColaApp *app = ((ZRColaApp*)wxTheApp);
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[event.GetId() - wxID_DECOMP_LANGUAGE_START]; const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[event.GetId() - wxID_DECOMP_LANGUAGE_START];
event.Check(memcmp(m_lang, lang.id, sizeof(m_lang)) == 0); event.Check(m_lang == lang.id);
} }
@ -345,8 +345,8 @@ void wxZRColaFrame::OnDecomposedLanguage(wxCommandEvent& event)
size_t i = event.GetId() - wxID_DECOMP_LANGUAGE_START; size_t i = event.GetId() - wxID_DECOMP_LANGUAGE_START;
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i]; const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i];
if (memcmp(m_lang, lang.id, sizeof(m_lang)) != 0) { if (m_lang != lang.id) {
memcpy(m_lang, lang.id, sizeof(m_lang)); m_lang = lang.id;
m_toolDecompLanguage->Select(i); m_toolDecompLanguage->Select(i);
// Notify composed text something changed and should re-decompose. // Notify composed text something changed and should re-decompose.
@ -363,8 +363,8 @@ void wxZRColaFrame::OnDecompLanguageChoice(wxCommandEvent& event)
size_t i = event.GetSelection(); size_t i = event.GetSelection();
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i]; const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i];
if (memcmp(m_lang, lang.id, sizeof(m_lang)) != 0) { if (m_lang != lang.id) {
memcpy(m_lang, lang.id, sizeof(m_lang)); m_lang = lang.id;
// Notify composed text something changed and should re-decompose. // Notify composed text something changed and should re-decompose.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED); wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
@ -563,7 +563,7 @@ void wxZRColaFrame::UpdateDecomposedLanguage()
// Find language on the language list. // Find language on the language list.
ZRCola::language_db::language *l = new ZRCola::language_db::language; ZRCola::language_db::language *l = new ZRCola::language_db::language;
memcpy(l->id, m_lang, sizeof(l->id)); l->id = m_lang;
l->name_len = 0; l->name_len = 0;
ZRCola::language_db::indexLang::size_type start; ZRCola::language_db::indexLang::size_type start;
m_toolDecompLanguage->SetSelection(app->m_lang_db.idxLng.find(*l, start) ? start : -1); m_toolDecompLanguage->SetSelection(app->m_lang_db.idxLng.find(*l, start) ? start : -1);
@ -639,7 +639,7 @@ void wxPersistentZRColaFrame::Save() const
wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Save(); wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Save();
SaveValue(wxT("langAuto" ), wnd->m_lang_auto); SaveValue(wxT("langAuto" ), wnd->m_lang_auto);
SaveValue(wxT("lang" ), wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang))); SaveValue(wxT("lang" ), wxString::FromAscii(wnd->m_lang.data, _countof(wnd->m_lang.data)));
wxPersistentTLW::Save(); wxPersistentTLW::Save();
} }
@ -663,12 +663,12 @@ bool wxPersistentZRColaFrame::Restore()
#endif #endif
} else if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) { } else if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) {
// The language was read from configuration. // The language was read from configuration.
memcpy(wnd->m_lang, (const char*)lang.c_str(), sizeof(wnd->m_lang)); wnd->m_lang = lang.c_str();
} else if (!app->m_lang_db.idxLng.empty()) { } else if (!app->m_lang_db.idxLng.empty()) {
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[0]; const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[0];
memcpy(wnd->m_lang, lang.id, sizeof(wnd->m_lang)); wnd->m_lang = lang.id;
} else } else
memcpy(wnd->m_lang, ZRCOLA_LANG_VOID, sizeof(wnd->m_lang)); wnd->m_lang = ZRCola::langid_t_blank;
wnd->UpdateDecomposedLanguage(); wnd->UpdateDecomposedLanguage();
wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Restore(); wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Restore();

View File

@ -400,9 +400,9 @@ bool ZRCola::DBSource::GetLanguage(const ATL::CComPtr<ADOField>& f, ZRCola::lang
_ftprintf(stderr, wxT("%s: error ZCC0081: Syntax error in \"%.*ls\" field (\"%.*ls\"). Language ID must contain ASCII characters only.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v)); _ftprintf(stderr, wxT("%s: error ZCC0081: Syntax error in \"%.*ls\" field (\"%.*ls\"). Language ID must contain ASCII characters only.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false; return false;
} }
lang[i] = (char)c; lang.data[i] = (char)c;
} else } else
lang[i] = 0; lang.data[i] = 0;
} else } else
break; break;
} }

View File

@ -243,7 +243,7 @@ int _tmain(int argc, _TCHAR *argv[])
// Add language to index and data. // Add language to index and data.
unsigned __int32 idx = db.data.size(); unsigned __int32 idx = db.data.size();
for (std::wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++) for (std::wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)lang.id)[i]); db.data.push_back(((const unsigned __int16*)lang.id.data)[i]);
std::wstring::size_type n = lang.name.length(); std::wstring::size_type n = lang.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("language name too long")); wxASSERT_MSG(n <= 0xffff, wxT("language name too long"));
db.data.push_back((unsigned __int16)n); db.data.push_back((unsigned __int16)n);
@ -297,7 +297,7 @@ int _tmain(int argc, _TCHAR *argv[])
unsigned __int32 idx = db.data.size(); unsigned __int32 idx = db.data.size();
db.data.push_back(lc.chr); db.data.push_back(lc.chr);
for (std::wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++) for (std::wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)lc.lang)[i]); db.data.push_back(((const unsigned __int16*)lc.lang.data)[i]);
db.idxChr.push_back(idx); db.idxChr.push_back(idx);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX #ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.push_back(idx); db.idxLng.push_back(idx);

View File

@ -52,11 +52,6 @@
/// ///
#define ZRCOLA_DB_ID (*(ZRCola::recordid_t*)"ZRC") #define ZRCOLA_DB_ID (*(ZRCola::recordid_t*)"ZRC")
///
/// Unknown language ID
///
#define ZRCOLA_LANG_VOID " "
namespace ZRCola { namespace ZRCola {
typedef unsigned __int32 recordid_t; typedef unsigned __int32 recordid_t;
@ -81,7 +76,143 @@ namespace ZRCola {
/// Language ID type /// Language ID type
/// Three letter abbreviation, zero terminated /// Three letter abbreviation, zero terminated
/// ///
typedef char langid_t[4]; struct langid_t {
char data[4];
inline langid_t& operator=(const langid_t &src)
{
data[0] = src.data[0];
data[1] = src.data[1];
data[2] = src.data[2];
data[3] = src.data[3];
return *this;
}
inline langid_t& operator=(const char *src)
{
data[3] = (
data[2] = (
data[1] = (
data[0] = src[0] ) != 0 ?
src[1] : 0) != 0 ?
src[2] : 0) != 0 ?
src[3] : 0;
return *this;
}
};
///
/// Blank language ID
///
const langid_t langid_t_blank = {};
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a == \p b
/// - false otherwise
///
inline bool operator==(const langid_t &a, const langid_t & b)
{
return
a.data[0] == b.data[0] &&
(a.data[0] == 0 || (a.data[1] == b.data[1] &&
(a.data[1] == 0 || (a.data[2] == b.data[2] &&
(a.data[2] == 0 || a.data[3] == b.data[3])))));
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a != \p b
/// - false otherwise
///
inline bool operator!=(const langid_t &a, const langid_t & b)
{
return !operator==(a, b);
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a < \p b
/// - false otherwise
///
inline bool operator<(const langid_t& a, const langid_t& b)
{
if (a.data[0] < b.data[0]) return true;
else if (a.data[0] > b.data[0]) return false;
else if (a.data[1] < b.data[1]) return true;
else if (a.data[1] > b.data[1]) return false;
else if (a.data[2] < b.data[2]) return true;
else if (a.data[2] > b.data[2]) return false;
else if (a.data[3] < b.data[3]) return true;
else return false;
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a > \p b
/// - false otherwise
///
inline bool operator>(const langid_t& a, const langid_t& b)
{
return operator<(b, a);
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a <= \p b
/// - false otherwise
///
inline bool operator<=(const langid_t &a, const langid_t & b)
{
return !operator>(a, b);
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a >= \p b
/// - false otherwise
///
inline bool operator>=(const langid_t &a, const langid_t & b)
{
return !operator<(a, b);
}
#ifdef _WIN32 #ifdef _WIN32

View File

@ -98,8 +98,8 @@ namespace ZRCola {
if (a.chr < b.chr) return -1; if (a.chr < b.chr) return -1;
else if (a.chr > b.chr) return 1; else if (a.chr > b.chr) return 1;
int r = memcmp(a.lang, b.lang, sizeof(langid_t)); if (a.lang < b.lang) return -1;
if (r != 0) return r; else if (a.lang > b.lang) return 1;
return 0; return 0;
} }
@ -234,8 +234,8 @@ namespace ZRCola {
/// ///
virtual int compare(_In_ const language &a, _In_ const language &b) const virtual int compare(_In_ const language &a, _In_ const language &b) const
{ {
int r = memcmp(a.id, b.id, sizeof(langid_t)); if (a.id < b.id) return -1;
if (r != 0) return r; else if (a.id > b.id) return 1;
return 0; return 0;
} }

View File

@ -224,7 +224,7 @@ namespace ZRCola {
/// ///
inline void Decompose(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map = NULL) const inline void Decompose(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map = NULL) const
{ {
Decompose(input, inputMax, NULL, ZRCOLA_LANG_VOID, output, map); Decompose(input, inputMax, NULL, langid_t_blank, output, map);
} }
/// ///

View File

@ -24,46 +24,46 @@
void ZRCola::LangConvert(_In_ LANGID lang_win, _Inout_ ZRCola::langid_t &lang) void ZRCola::LangConvert(_In_ LANGID lang_win, _Inout_ ZRCola::langid_t &lang)
{ {
switch (PRIMARYLANGID(lang_win)) { switch (PRIMARYLANGID(lang_win)) {
case LANG_BELARUSIAN : memcpy(lang, "bel", sizeof(lang)); break; case LANG_BELARUSIAN : lang = "bel"; break;
case LANG_CZECH : memcpy(lang, "cze", sizeof(lang)); break; case LANG_CZECH : lang = "cze"; break;
case LANG_DANISH : memcpy(lang, "dan", sizeof(lang)); break; case LANG_DANISH : lang = "dan"; break;
case LANG_GERMAN : memcpy(lang, "deu", sizeof(lang)); break; case LANG_GERMAN : lang = "deu"; break;
case LANG_ENGLISH : memcpy(lang, "eng", sizeof(lang)); break; case LANG_ENGLISH : lang = "eng"; break;
case LANG_ESTONIAN : memcpy(lang, "est", sizeof(lang)); break; case LANG_ESTONIAN : lang = "est"; break;
case LANG_FRENCH : memcpy(lang, "fra", sizeof(lang)); break; case LANG_FRENCH : lang = "fra"; break;
case LANG_IRISH : memcpy(lang, "gle", sizeof(lang)); break; case LANG_IRISH : lang = "gle"; break;
case LANG_HUNGARIAN : memcpy(lang, "hun", sizeof(lang)); break; case LANG_HUNGARIAN : lang = "hun"; break;
case LANG_LATVIAN : memcpy(lang, "lav", sizeof(lang)); break; case LANG_LATVIAN : lang = "lav"; break;
case LANG_LITHUANIAN : memcpy(lang, "lit", sizeof(lang)); break; case LANG_LITHUANIAN : lang = "lit"; break;
case LANG_MACEDONIAN : memcpy(lang, "mkd", sizeof(lang)); break; case LANG_MACEDONIAN : lang = "mkd"; break;
case LANG_MALTESE : memcpy(lang, "mlt", sizeof(lang)); break; case LANG_MALTESE : lang = "mlt"; break;
case LANG_NORWEGIAN : memcpy(lang, "nor", sizeof(lang)); break; case LANG_NORWEGIAN : lang = "nor"; break;
case LANG_POLISH : memcpy(lang, "pol", sizeof(lang)); break; case LANG_POLISH : lang = "pol"; break;
case LANG_PORTUGUESE : memcpy(lang, "por", sizeof(lang)); break; case LANG_PORTUGUESE : lang = "por"; break;
case LANG_ROMANIAN : memcpy(lang, "rum", sizeof(lang)); break; case LANG_ROMANIAN : lang = "rum"; break;
case LANG_RUSSIAN : memcpy(lang, "rus", sizeof(lang)); break; case LANG_RUSSIAN : lang = "rus"; break;
case LANG_SLOVAK : memcpy(lang, "slk", sizeof(lang)); break; case LANG_SLOVAK : lang = "slk"; break;
case LANG_SLOVENIAN : memcpy(lang, "slv", sizeof(lang)); break; case LANG_SLOVENIAN : lang = "slv"; break;
case LANG_SPANISH : memcpy(lang, "spa", sizeof(lang)); break; case LANG_SPANISH : lang = "spa"; break;
case LANG_ALBANIAN : memcpy(lang, "sqi", sizeof(lang)); break; case LANG_ALBANIAN : lang = "sqi"; break;
case LANG_SWEDISH : memcpy(lang, "swe", sizeof(lang)); break; case LANG_SWEDISH : lang = "swe"; break;
case LANG_TURKISH : memcpy(lang, "tur", sizeof(lang)); break; case LANG_TURKISH : lang = "tur"; break;
case LANG_UKRAINIAN : memcpy(lang, "ukr", sizeof(lang)); break; case LANG_UKRAINIAN : lang = "ukr"; break;
case LANG_CROATIAN : // LANG_BOSNIAN, and LANG_SERBIAN case LANG_CROATIAN : // LANG_BOSNIAN, and LANG_SERBIAN
switch (SUBLANGID(lang_win)) { switch (SUBLANGID(lang_win)) {
case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN : memcpy(lang, "bos", sizeof(lang)); break; case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN : lang = "bos"; break;
case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC : memcpy(lang, "boz", sizeof(lang)); break; case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC : lang = "boz"; break;
case SUBLANG_CROATIAN_CROATIA : case SUBLANG_CROATIAN_CROATIA :
case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN : memcpy(lang, "hrv", sizeof(lang)); break; case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN : lang = "hrv"; break;
case SUBLANG_SERBIAN_LATIN : case SUBLANG_SERBIAN_LATIN :
case SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN : case SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN :
case SUBLANG_SERBIAN_MONTENEGRO_LATIN : case SUBLANG_SERBIAN_MONTENEGRO_LATIN :
case SUBLANG_SERBIAN_SERBIA_LATIN : memcpy(lang, "srp", sizeof(lang)); break; case SUBLANG_SERBIAN_SERBIA_LATIN : lang = "srp"; break;
case SUBLANG_SERBIAN_CYRILLIC : case SUBLANG_SERBIAN_CYRILLIC :
case SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC : case SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC :
case SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC : case SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC :
case SUBLANG_SERBIAN_SERBIA_CYRILLIC : memcpy(lang, "srz", sizeof(lang)); break; case SUBLANG_SERBIAN_SERBIA_CYRILLIC : lang = "srz"; break;
} }
break; break;
} }
@ -83,9 +83,8 @@ bool ZRCola::langchar_db::IsLocalCharacter(_In_ wchar_t chr, _In_ ZRCola::langid
else if (lc.chr < chr ) l = m + 1; else if (lc.chr < chr ) l = m + 1;
else { else {
// Do the bisection test on language. // Do the bisection test on language.
int res = memcmp(lang, lc.lang, sizeof(langid_t)); if (lang < lc.lang) r = m;
if (res < 0) r = m; else if (lang > lc.lang) l = m + 1;
else if (res > 0) l = m + 1;
else { else {
// Match found. // Match found.
return true; return true;