From a433db8a4fd7b4bacef93123b19e7620dee89f5a Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Sat, 28 Mar 2020 08:32:29 +0100 Subject: [PATCH] + fix: locale dependent string comparision --- Versions/day.txt | 2 +- res/Notepad3.exe.manifest.conf | 2 +- src/Edit.c | 39 ++++++++++++++++------------------ src/Encoding.c | 2 +- src/Helpers.h | 26 ++++++++++++++++++++++- src/MuiLanguage.c | 20 ++++++++++++++++- src/VersionEx.h | 4 ++-- 7 files changed, 67 insertions(+), 28 deletions(-) diff --git a/Versions/day.txt b/Versions/day.txt index 27a69f601..86619979c 100644 --- a/Versions/day.txt +++ b/Versions/day.txt @@ -1 +1 @@ -327 +328 diff --git a/res/Notepad3.exe.manifest.conf b/res/Notepad3.exe.manifest.conf index 1064ecf45..22830e86b 100644 --- a/res/Notepad3.exe.manifest.conf +++ b/res/Notepad3.exe.manifest.conf @@ -3,7 +3,7 @@ Notepad3 RC3 diff --git a/src/Edit.c b/src/Edit.c index e43f1164a..2732f8b73 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -4634,16 +4634,18 @@ typedef int (__stdcall * FNSTRLOGCMP)(LPCWSTR, LPCWSTR); // ---------------------------------------------------------------------------- int CmpStd(const void *s1, const void *s2) { - int const cmp = StrCmp(((SORTLINE*)s1)->pwszSortEntry,((SORTLINE*)s2)->pwszSortEntry); - return (cmp) ? cmp : StrCmp(((SORTLINE*)s1)->pwszLine,((SORTLINE*)s2)->pwszLine); + //~StrCmp() + int const cmp = wcscoll_s(((SORTLINE*)s1)->pwszSortEntry, ((SORTLINE*)s2)->pwszSortEntry); + return (cmp) ? cmp : wcscoll_s(((SORTLINE*)s1)->pwszLine, ((SORTLINE*)s2)->pwszLine); } int CmpStdRev(const void* s1, const void* s2) { return -1 * CmpStd(s1, s2); } int CmpStdI(const void* s1, const void* s2) { - int const cmp = StrCmpI(((SORTLINE*)s1)->pwszSortEntry, ((SORTLINE*)s2)->pwszSortEntry); - return (cmp) ? cmp : StrCmpI(((SORTLINE*)s1)->pwszLine, ((SORTLINE*)s2)->pwszLine); + //~StrCmpI() + int const cmp = wcsicoll_s(((SORTLINE*)s1)->pwszSortEntry, ((SORTLINE*)s2)->pwszSortEntry); + return (cmp) ? cmp : wcsicoll_s(((SORTLINE*)s1)->pwszLine, ((SORTLINE*)s2)->pwszLine); } int CmpStdIRev(const void* s1, const void* s2) { return -1 * CmpStdI(s1, s2); } @@ -4651,14 +4653,9 @@ int CmpStdIRev(const void* s1, const void* s2) { return -1 * CmpStdI(s1, s2); } // ---------------------------------------------------------------------------- int CmpLexicographical(const void *s1, const void *s2) { - LPCWSTR const pwszSE1 = ((SORTLINE*)s1)->pwszSortEntry; - LPCWSTR const pwszSE2 = ((SORTLINE*)s2)->pwszSortEntry; - if (pwszSE1 && pwszSE2) { - int const cmp = wcscmp(pwszSE1, pwszSE2); - return (cmp) ? cmp : wcscmp(((SORTLINE*)s1)->pwszLine, ((SORTLINE*)s2)->pwszLine); + int const cmp = wcscmp_s(((SORTLINE*)s1)->pwszSortEntry, ((SORTLINE*)s2)->pwszSortEntry); + return (cmp) ? cmp : wcscmp_s(((SORTLINE*)s1)->pwszLine, ((SORTLINE*)s2)->pwszLine); } - return pwszSE1 ? -1 : (pwszSE2 ? 1 : 0); -} //int CmpLexicographicalI(const void* s1, const void* s2) { // int const cmp = _wcsicmp(((SORTLINE*)s1)->pwszSortEntry, ((SORTLINE*)s2)->pwszSortEntry); @@ -4734,14 +4731,14 @@ void EditSortLines(HWND hwnd, int iSortFlags) DocPos iMaxLineLen = Sci_GetRangeMaxLineLength(iLineStart, iLineEnd); char* pmsz = AllocMem(iMaxLineLen + 1, HEAP_ZERO_MEMORY); + int ichlMax = 3; DocPos cchTotal = 0; - DocPos ichlMax = 3; DocLn iZeroLenLineCount = 0; for (DocLn i = 0, iLn = iLineStart; iLn <= iLineEnd; ++iLn, ++i) { - DocPos const cchm = SciCall_LineLength(iLn); + int const cchm = (int)SciCall_LineLength(iLn); cchTotal += cchm; - ichlMax = max_p(ichlMax, cchm); + ichlMax = max_i(ichlMax, cchm); SciCall_GetLine_Safe(iLn, pmsz); @@ -4754,12 +4751,12 @@ void EditSortLines(HWND hwnd, int iSortFlags) } StrTrimA(pmsz, "\r\n"); // ignore line-breaks - ptrdiff_t const cchw = MultiByteToWideCharEx(Encoding_SciCP, 0, pmsz, -1, NULL, 0) - 1; - if (cchw > 0) { + int const cchw = MultiByteToWideChar(Encoding_SciCP, 0, pmsz, -1, NULL, 0); + if (cchw > 1) { int tabs = _iTabWidth; - ptrdiff_t const lnLen = (sizeof(WCHAR) * (cchw + 1)); + ptrdiff_t const lnLen = (sizeof(WCHAR) * cchw); pLines[i].pwszLine = AllocMem(lnLen, HEAP_ZERO_MEMORY); - MultiByteToWideCharEx(Encoding_SciCP, 0, pmsz, -1, pLines[i].pwszLine, lnLen / sizeof(WCHAR)); + MultiByteToWideChar(Encoding_SciCP, 0, pmsz, -1, pLines[i].pwszLine, cchw); pLines[i].pwszSortEntry = pLines[i].pwszLine; if (iSortFlags & SORT_COLUMN) { int col = 0; @@ -4828,7 +4825,8 @@ void EditSortLines(HWND hwnd, int iSortFlags) char* pmszResOffset = pmszResult; char* pmszBuf = AllocMem(ichlMax + 1, HEAP_ZERO_MEMORY); - FNSTRCMP const pFctStrCmp = (iSortFlags & SORT_NOCASE) ? StrCmpI : StrCmp; + FNSTRCMP const pFctStrCmp = (iSortFlags & SORT_NOCASE) ? ((iSortFlags & SORT_LEXICOGRAPH) ? wcsicmp_s : wcsicoll_s) : + ((iSortFlags & SORT_LEXICOGRAPH) ? wcscmp_s : wcscoll_s); bool bLastDup = false; for (DocLn i = 0; i < iLineCount; ++i) { @@ -4853,8 +4851,7 @@ void EditSortLines(HWND hwnd, int iSortFlags) } } if (!bDropLine) { - WideCharToMultiByteEx(Encoding_SciCP, 0, pLines[i].pwszLine, -1, - pmszBuf, (ichlMax + 1), NULL, NULL); + WideCharToMultiByte(Encoding_SciCP, 0, pLines[i].pwszLine, -1, pmszBuf, (ichlMax + 1), NULL, NULL); StringCchCatA(pmszResult, lenRes, pmszBuf); StringCchCatA(pmszResult, lenRes, mszEOL); } diff --git a/src/Encoding.c b/src/Encoding.c index f2ad00f58..0b80c1247 100644 --- a/src/Encoding.c +++ b/src/Encoding.c @@ -325,7 +325,7 @@ typedef struct _ee { ENCODINGENTRY, *PENCODINGENTRY; int CmpEncoding(const void *s1, const void *s2) { - return StrCmp(((const PENCODINGENTRY)s1)->wch, ((const PENCODINGENTRY)s2)->wch); + return wcscmp_s(((const PENCODINGENTRY)s1)->wch, ((const PENCODINGENTRY)s2)->wch); } // ============================================================================ diff --git a/src/Helpers.h b/src/Helpers.h index 048614dac..beda32bfd 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -24,7 +24,7 @@ #include #include -#include +#include "Scintilla.h" // ============================================================================ // --- Disable/Enable some CodeAnalysis Warnings --- @@ -381,6 +381,29 @@ __inline ptrdiff_t MultiByteToWideCharEx( #endif +// ============================================================================ + +inline int wcscmp_s(const wchar_t* s1, const wchar_t* s2) +{ + return (s1 && s2) ? wcscmp(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); +} + +inline int wcscoll_s(const wchar_t* s1, const wchar_t* s2) +{ + return (s1 && s2) ? wcscoll(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); +} + +inline int wcsicmp_s(const wchar_t* s1, const wchar_t* s2) +{ + return (s1 && s2) ? _wcsicmp(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); +} + +inline int wcsicoll_s(const wchar_t* s1, const wchar_t* s2) +{ + return (s1 && s2) ? _wcsicoll(s1, s2) : ((s1 ? 1 : (s2 ? -1 : 0))); +} + +// ============================================================================ inline void SwabEx(char* src, char* dest, size_t n) { @@ -564,6 +587,7 @@ inline HRESULT PathCchCanonicalize(PWSTR p,size_t l,PCWSTR a) { UNUSED(l); re inline HRESULT PathCchRenameExtension(PWSTR p,size_t l,PCWSTR a) { UNUSED(l); return (PathRenameExtension(p,a) ? S_OK : E_FAIL); } inline HRESULT PathCchRemoveFileSpec(PWSTR p,size_t l) { UNUSED(l); return (PathRemoveFileSpec(p) ? S_OK : E_FAIL); } +// ---------------------------------------------------------------------------- #endif //_NP3_HELPERS_H_ diff --git a/src/MuiLanguage.c b/src/MuiLanguage.c index f50084190..6d78a1bbe 100644 --- a/src/MuiLanguage.c +++ b/src/MuiLanguage.c @@ -214,19 +214,37 @@ bool GetUserPreferredLanguage(LPWSTR pszPrefLocaleName, int cchBuffer, LANGID* p // // SetPreferredLanguage // +static void SetMuiLocaleAll(LPCWSTR pszLocaleStr) +{ + const WCHAR* const pszLocaleCur = _wsetlocale(LC_ALL, pszLocaleStr); +#ifdef _DEBUG + if (StringCchCompareXI(pszLocaleStr, pszLocaleCur) != 0) { + //const _locale_t pCurLocale = _get_current_locale(); + WCHAR msg[128]; + StringCchPrintf(msg, COUNTOF(msg), L"Can't set desired locale '%s', using '%s' instead!", + pszLocaleStr, pszLocaleCur ? pszLocaleCur : L""); + MsgBoxLastError(msg, ERROR_MUI_INVALID_LOCALE_NAME); + } +#endif +} + void SetPreferredLanguage(LANGID iPreferredLanguageID) { int const langIdx = GetMUILanguageIndexByLangID(iPreferredLanguageID); if (langIdx < 0) { Globals.iPrefLANGID = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); // internal + SetMuiLocaleAll(MUI_LanguageDLLs[0].szLocaleName); return; } if (iPreferredLanguageID != Globals.iPrefLANGID) { Globals.iPrefLANGID = iPreferredLanguageID; // == MUI_LanguageDLLs[langIdx].LangId - const WCHAR* szLocaleName = MUI_LanguageDLLs[langIdx].szLocaleName; + + const WCHAR* const szLocaleName = MUI_LanguageDLLs[langIdx].szLocaleName; + + SetMuiLocaleAll(szLocaleName); if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, szLocaleName) != 0) { diff --git a/src/VersionEx.h b/src/VersionEx.h index 60efb770e..d91a9f9fd 100644 --- a/src/VersionEx.h +++ b/src/VersionEx.h @@ -8,7 +8,7 @@ #define SAPPNAME "Notepad3" #define VERSION_MAJOR 5 #define VERSION_MINOR 20 -#define VERSION_REV 327 +#define VERSION_REV 328 #define VERSION_BUILD 1 #define SCINTILLA_VER 432 #define ONIGURUMA_REGEX_VER 6.9.4 @@ -16,4 +16,4 @@ #define TINYEXPR_VER 2018.05.11 #define UTHASH_VER 2.1.0 #define VERSION_PATCH RC3 -#define VERSION_COMMIT_ID t7820-rk +#define VERSION_COMMIT_ID nebukadn