From 7ad11ca9d2a55372351d23adde12dee5ce16d99e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 29 Sep 2020 14:25:57 +1000 Subject: [PATCH 01/20] fix(windows): Upgrading keyboards with transient profiles Relates to #3561. If a keyboard has languages installed under one of the four transient language profiles, then we need to jump through some additional hoops to upgrade it to the 14.0 model. This does not yet handle all scenarios around installed but non-loaded keyboards. --- ...tem.UImportOlderVersionKeyboards11To13.pas | 90 +++++++++++++++++-- ...yman.System.CanonicalLanguageCodeUtils.pas | 2 - 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas b/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas index f8ab24439e..c0cb2635b6 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas @@ -52,6 +52,7 @@ end; type TUpgradeKeyboard = record KeyboardID: string; + BCP47Code: string; LangID: Integer; end; TUpgradeKeyboardList = class(TList); @@ -85,6 +86,7 @@ class procedure TImportOlderVersionKeyboards11To13.BackupCurrentUser; begin uk.KeyboardID := keyboard; uk.LangID := r.ReadInteger(SRegValue_LanguageProfileLangID); + uk.BCP47Code := profile; Result.Add(uk); end; end; @@ -101,19 +103,27 @@ var r: TRegistry; i: Integer; uks: TUpgradeKeyboardList; + uk: TUpgradeKeyboard; begin - // TODO: figure out Keyman "disabled" keyboards - // TODO: figure out transient language registrations uks := LoadUpgradeKeyboards; r := TRegistry.Create; try if not r.OpenKey(SRegKey_Keyman_Temp_BackupProfiles, True) then Exit; - for i := 0 to uks.Count - 1 do + i := 0; + for uk in uks do begin - r.WriteString(IntToStr(i), uks[i].KeyboardID+'='+IntToStr(uks[i].LangID)); + + // For transient language codes, we will need to install using an assigned id + // which may vary, so we will work from the BCP47 code. + if IsTransientLanguageID(uk.LangID) + then r.WriteString(IntToStr(i), uk.KeyboardID+'='+uk.BCP47Code) + else r.WriteString(IntToStr(i), uk.KeyboardID+'='+IntToStr(uk.LangID)); + Inc(i); end; + + // TODO: save keyboards that are disabled (i.e. listed in Installed but not Active) finally r.Free; uks.Free; @@ -180,6 +190,13 @@ var strings: TStringList; s: string; p: TArray; + BCP47Code, KeyboardID: string; + LangID: Integer; + kbd: IKeymanKeyboardInstalled; + lang: IKeymanKeyboardLanguageInstalled2; + TemporaryKeyboardID: WideString; + RegistrationRequired: WordBool; + i: Integer; begin r := TRegistry.Create; strings := TStringList.Create; @@ -191,9 +208,70 @@ begin for s in strings do begin - // each string is saved in BackupCurrentUser and is keyboardid=langid + // each string is saved in BackupCurrentUser and is keyboardid=langid|bcp47 p := r.ReadString(s).Split(['=']); - kmcom.Keyboards[p[0]].Languages.InstallByLangID(StrToInt(p[1])); + KeyboardID := p[0]; + BCP47Code := p[1]; + LangID := StrToIntDef(BCP47Code, 0); + kbd := kmcom.Keyboards[KeyboardID]; + if not Assigned(kbd) then + begin + // Avoid errors if a package is uninstalled midway through + Continue; + end; + + if LangID = 0 then + begin + // Installing a transient language is a 2-step process. We can assume that + // the transient language codes have been installed correctly as Register + // would have been called immediately prior to this. + lang := nil; + BCP47Code := (kmcom as IKeymanBCP47Canonicalization).GetCanonicalTag(BCP47Code); + for i := 0 to kbd.Languages.Count - 1 do + begin + if SameText(kbd.Languages[i].BCP47Code, BCP47Code) then + begin + lang := kbd.Languages[i] as IKeymanKeyboardLanguageInstalled2; + Break; + end; + end; + + if lang = nil then + begin + // The BCP47 code was not in the list of languages; this could possibly + // happen if we had registered a code that was canonicalized differently + // in the past? + lang := (kbd.Languages as IKeymanKeyboardLanguagesInstalled2).Add(BCP47Code) as IKeymanKeyboardLanguageInstalled2; + if lang = nil then + begin + // This should never happen, because .Add only fails if the language + // is already in the list, which we just searched through, or if the + // BCP47Code is empty + Continue; + end; + end; + + if lang.IsInstalled then + begin + // Don't attempt to reinstall; this should not normally be the case but + // if we canonicalize two languages which were previously installed into + // a single code, then in theory this could happen. + Continue; + end; + + if lang.FindInstallationLangID(LangID, TemporaryKeyboardID, RegistrationRequired, kifInstallTransientLanguage) then + begin + if not RegistrationRequired then + lang.InstallTip(LangID, TemporaryKeyboardID) + else + begin + // This should not happen; installed languages would have been registered + // in the Register step. + end; + end; + end + else + kbd.Languages.InstallByLangID(LangID); end; r.CloseKey; diff --git a/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas b/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas index 539ce1db3e..47efb21066 100644 --- a/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas +++ b/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas @@ -17,8 +17,6 @@ uses Keyman.System.Standards.LangTagsRegistry, System.SysUtils; -// TODO: Make this a COM API function so we aren't shipping 3+MB of standards data multiple times - /// ///Find a language code with appropriate script and region subtags /// From 827ea6c3868cd78c7036532648a30e3a74e9ef58 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 29 Sep 2020 20:25:10 +1000 Subject: [PATCH 02/20] fix(windows): upgrading disabled keyboards Fixes #3561. Resolves issues with upgrading disabled keyboards, and fixes a secondary issue where Windows was giving us invalid LANGIDs for locales, which was causing trouble with transient LANGIDs. --- ...tem.UImportOlderVersionKeyboards11To13.pas | 121 ++++++++++-------- ...stem.Process.KPInstallKeyboardLanguage.pas | 17 +++ 2 files changed, 82 insertions(+), 56 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas b/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas index c0cb2635b6..faad0d9454 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas @@ -32,6 +32,7 @@ uses UImportOlderVersionKeyboards9Plus, UImportOlderKeyboardUtils, utilexecute, + utilkmshell, utiltsf; class procedure TImportOlderVersionKeyboards11To13.Execute; // I2361 @@ -53,7 +54,6 @@ type TUpgradeKeyboard = record KeyboardID: string; BCP47Code: string; - LangID: Integer; end; TUpgradeKeyboardList = class(TList); @@ -82,13 +82,9 @@ class procedure TImportOlderVersionKeyboards11To13.BackupCurrentUser; r.GetKeyNames(profiles); for profile in profiles do begin - if r.OpenKeyReadOnly('\' + BuildKeyboardLanguageProfilesKey_LM(keyboard) + '\' + profile) and r.ValueExists(SRegValue_LanguageProfileLangID) then - begin - uk.KeyboardID := keyboard; - uk.LangID := r.ReadInteger(SRegValue_LanguageProfileLangID); - uk.BCP47Code := profile; - Result.Add(uk); - end; + uk.KeyboardID := keyboard; + uk.BCP47Code := profile; + Result.Add(uk); end; end; end; @@ -114,16 +110,12 @@ begin i := 0; for uk in uks do begin - // For transient language codes, we will need to install using an assigned id // which may vary, so we will work from the BCP47 code. - if IsTransientLanguageID(uk.LangID) - then r.WriteString(IntToStr(i), uk.KeyboardID+'='+uk.BCP47Code) - else r.WriteString(IntToStr(i), uk.KeyboardID+'='+IntToStr(uk.LangID)); + r.WriteString(IntToStr(i), uk.KeyboardID+'='+uk.BCP47Code); Inc(i); end; - // TODO: save keyboards that are disabled (i.e. listed in Installed but not Active) finally r.Free; uks.Free; @@ -180,6 +172,7 @@ begin keys.Free; end; + // The following code re-registers all the profiles kmcom.Refresh; (kmcom.Keyboards as IKeymanKeyboardsInstalled2).RefreshInstalledKeyboards; end; @@ -208,11 +201,10 @@ begin for s in strings do begin - // each string is saved in BackupCurrentUser and is keyboardid=langid|bcp47 + // each string is saved in BackupCurrentUser and is keyboardid=bcp47 p := r.ReadString(s).Split(['=']); KeyboardID := p[0]; BCP47Code := p[1]; - LangID := StrToIntDef(BCP47Code, 0); kbd := kmcom.Keyboards[KeyboardID]; if not Assigned(kbd) then begin @@ -220,66 +212,83 @@ begin Continue; end; - if LangID = 0 then + // Installing a language is a 2-step process. (We can assume that + // the transient language codes have been installed correctly as Register + // would have been called immediately prior to this.) + lang := nil; + BCP47Code := (kmcom as IKeymanBCP47Canonicalization).GetCanonicalTag(BCP47Code); + for i := 0 to kbd.Languages.Count - 1 do begin - // Installing a transient language is a 2-step process. We can assume that - // the transient language codes have been installed correctly as Register - // would have been called immediately prior to this. - lang := nil; - BCP47Code := (kmcom as IKeymanBCP47Canonicalization).GetCanonicalTag(BCP47Code); - for i := 0 to kbd.Languages.Count - 1 do + if SameText(kbd.Languages[i].BCP47Code, BCP47Code) then begin - if SameText(kbd.Languages[i].BCP47Code, BCP47Code) then - begin - lang := kbd.Languages[i] as IKeymanKeyboardLanguageInstalled2; - Break; - end; + lang := kbd.Languages[i] as IKeymanKeyboardLanguageInstalled2; + Break; end; + end; + if lang = nil then + begin + // The BCP47 code was not in the list of languages; this could possibly + // happen if we had registered a code that was canonicalized differently + // in the past? + lang := (kbd.Languages as IKeymanKeyboardLanguagesInstalled2).Add(BCP47Code) as IKeymanKeyboardLanguageInstalled2; if lang = nil then begin - // The BCP47 code was not in the list of languages; this could possibly - // happen if we had registered a code that was canonicalized differently - // in the past? - lang := (kbd.Languages as IKeymanKeyboardLanguagesInstalled2).Add(BCP47Code) as IKeymanKeyboardLanguageInstalled2; - if lang = nil then - begin - // This should never happen, because .Add only fails if the language - // is already in the list, which we just searched through, or if the - // BCP47Code is empty - Continue; - end; - end; - - if lang.IsInstalled then - begin - // Don't attempt to reinstall; this should not normally be the case but - // if we canonicalize two languages which were previously installed into - // a single code, then in theory this could happen. + // This should never happen, because .Add only fails if the language + // is already in the list, which we just searched through, or if the + // BCP47Code is empty Continue; end; + end; - if lang.FindInstallationLangID(LangID, TemporaryKeyboardID, RegistrationRequired, kifInstallTransientLanguage) then + if lang.IsInstalled then + begin + // Don't attempt to reinstall; this should not normally be the case but + // if we canonicalize two languages which were previously installed into + // a single code, then in theory this could happen. + Continue; + end; + + if lang.FindInstallationLangID(LangID, TemporaryKeyboardID, RegistrationRequired, kifInstallTransientLanguage) then + begin + if RegistrationRequired then begin - if not RegistrationRequired then - lang.InstallTip(LangID, TemporaryKeyboardID) - else - begin - // This should not happen; installed languages would have been registered - // in the Register step. - end; + // This can happen for custom language codes. TODO: This is not ideal because of potential for multiple elevation prompts + WaitForElevatedConfiguration(0, '-register-tip '+IntToHex(LangID,4)+' "'+KeyboardID+'" "'+lang.BCP47Code+'"'); end; - end - else - kbd.Languages.InstallByLangID(LangID); + + lang.InstallTip(LangID, TemporaryKeyboardID); + end; end; r.CloseKey; r.DeleteKey(SRegKey_Keyman_Temp_BackupProfiles); + + // + // Reapply the loaded state for keyboards; this may cause TIPs to disappear again + // + + kmcom.Refresh; + + if r.OpenKeyReadOnly('\' + SRegKey_ActiveKeyboards_CU) then + begin + strings.Clear; + r.GetKeyNames(strings); + for s in strings do + begin + kbd := kmcom.Keyboards[s]; + if Assigned(kbd) then + kbd.Loaded := r.OpenKeyReadOnly('\' + SRegKey_ActiveKeyboards_CU + '\' + s) and r.ValueExists(SRegValue_KeymanID); + end; + end; + finally strings.Free; r.Free; end; + + kmcom.Apply; + kmcom.Refresh; end; end. diff --git a/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas b/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas index d7a0791710..ead129c382 100644 --- a/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas +++ b/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas @@ -236,6 +236,23 @@ begin LangID := LocaleNameToLCID(PWideChar(Locale), 0); + if (PRIMARYLANGID(LangID) = 0) and ( + (SUBLANGID(LangID) < 8) or + (SUBLANGID(LangID) > 11) + ) then + begin + // LocaleNameToLCID can return a language code that is 'transient' but + // outside of the supported range of $2000, $2400, $2800, $2C00. For + // example, we have seen values of $3000, $3400, $3800. + // Set-WinUserLanguageList refuses to play ball with these values, so we + // reject them as invalid. + // + // This may be a bug in Windows? TODO: Investigate further and report to + // Microsoft + Exit(False); + end; + + case LangID of LOCALE_CUSTOM_DEFAULT, LOCALE_CUSTOM_UNSPECIFIED, From dd4ac894685f7e0bbda347c911128094afbc0394 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 30 Sep 2020 11:54:51 +1000 Subject: [PATCH 03/20] fix(developer): coverity issues for compiler.cpp CID 309307 through 309313, 309318, 309321, 309371, 309388. --- windows/src/developer/kmcmpdll/Compiler.cpp | 34 ++++++++++++--------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/windows/src/developer/kmcmpdll/Compiler.cpp b/windows/src/developer/kmcmpdll/Compiler.cpp index 7125203d02..a5262b5c67 100644 --- a/windows/src/developer/kmcmpdll/Compiler.cpp +++ b/windows/src/developer/kmcmpdll/Compiler.cpp @@ -447,11 +447,14 @@ BOOL CompileKeyboardHandle(HANDLE hInfile, PFILE_KEYBOARD fk) FMnemonicLayout = FALSE; - str = new WCHAR[LINESIZE]; - if(!str) SetError(CERR_CannotAllocateMemory); + if (!fk) { + SetError(CERR_SomewhereIGotItWrong); + } - //fk = new FILE_KEYBOARD; - if(!fk) SetError(CERR_CannotAllocateMemory); + str = new WCHAR[LINESIZE]; + if (!str) { + SetError(CERR_CannotAllocateMemory); + } fk->KeyboardID = 0; fk->version = 0; @@ -1115,7 +1118,7 @@ DWORD AddDebugStore(PFILE_KEYBOARD fk, PWSTR str) if(fk->dpStoreArray) { memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); - delete fk->dpStoreArray; + delete[] fk->dpStoreArray; } fk->dpStoreArray = sp; @@ -1346,7 +1349,10 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) j = SUBLANGID(n); i = PRIMARYLANGID(n); - if(i < 1 || j < 1 || i > 0x3FF || j > 0x3F) return CERR_InvalidLanguageLine; + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) { + delete q; + return CERR_InvalidLanguageLine; + } swprintf(r, szQ - (size_t)(r-q), L"x%04.4x ", n); // I3481 @@ -1427,7 +1433,7 @@ BOOL GetFileVersion(char *filename, WORD *d1, WORD *d2, WORD *d3, WORD *d4) *d3 = HIWORD(vffi->dwFileVersionLS); *d4 = LOWORD(vffi->dwFileVersionLS); - delete p; + delete[] p; return TRUE; } @@ -2521,7 +2527,7 @@ DWORD process_if_synonym(DWORD dwSystemID, PFILE_KEYBOARD fk, LPWSTR q, LPWSTR t tstr[(*mx)++] = (WCHAR)(dwStoreID+1); tstr[(*mx)] = 0; - delete temp; + delete[] temp; return CERR_None; } @@ -2574,7 +2580,7 @@ DWORD process_if(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) // I3431 if((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) { - delete temp; + delete[] temp; return msg; } @@ -2582,7 +2588,7 @@ DWORD process_if(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) // I3431 if((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) { - delete temp; + delete[] temp; return msg; } @@ -3203,7 +3209,7 @@ DWORD GetRHS(PFILE_KEYBOARD fk, PWSTR p, PWSTR buf, int bufsize, int offset, int void safe_wcsncpy(PWSTR out, PWSTR in, int cbMax) { - wcsncpy_s(out, cbMax, in, cbMax); // I3481 + wcsncpy_s(out, cbMax, in, cbMax - 1); // I3481 out[cbMax-1] = 0; } @@ -3354,7 +3360,7 @@ DWORD BuildVKDictionary(PFILE_KEYBOARD fk) // I3438 DWORD dwStoreID; DWORD msg = AddStore(fk, TSS_VKDICTIONARY, storeval, &dwStoreID); - delete storeval; + delete[] storeval; return msg; } @@ -3392,7 +3398,7 @@ int GetDeadKey(PFILE_KEYBOARD fk, PWSTR p) { PFILE_DEADKEY dk = new FILE_DEADKEY[fk->cxDeadKeyArray+10]; memcpy(dk, fk->dpDeadKeyArray, fk->cxDeadKeyArray * sizeof(FILE_DEADKEY)); - delete fk->dpDeadKeyArray; + delete[] fk->dpDeadKeyArray; fk->dpDeadKeyArray = dk; } wcsncpy_s(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName, _countof(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName), p, SZMAX_DEADKEYNAME); // I3481 @@ -3408,7 +3414,7 @@ void RecordDeadkeyNames(PFILE_KEYBOARD fk) DWORD i; for(i = 0; i < fk->cxDeadKeyArray; i++) { - swprintf(buf, _countof(buf), L"%s%d %s", DEBUGSTORE_DEADKEY, i, fk->dpDeadKeyArray[i].szName); // I3481 + swprintf(buf, _countof(buf), L"%ls%d %ls", DEBUGSTORE_DEADKEY, i, fk->dpDeadKeyArray[i].szName); // I3481 AddDebugStore(fk, buf); } } From 508441ebf46e0f640273a1c6eda0b7ae3ee6e335 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 30 Sep 2020 14:20:41 +1000 Subject: [PATCH 04/20] fix(developer): coverity reports for compiler Addresses Coverity reports for compiler.cpp and other files. Note that whitespace was reformatted on this PR. You may want to compare with ignore-whitespace. --- windows/src/Makefile | 6 + windows/src/developer/kmcmpdll/Compiler.cpp | 4084 +++++++++-------- .../developer/kmcmpdll/NamedCodeConstants.cpp | 19 +- windows/src/developer/kmcmpdll/kcframe.cpp | 2 +- windows/src/developer/kmcmpdll/kmcmpdll.h | 4 +- windows/src/developer/kmcmpdll/versioning.cpp | 2 +- 6 files changed, 2071 insertions(+), 2046 deletions(-) diff --git a/windows/src/Makefile b/windows/src/Makefile index 1d6e3e8a5c..d89939aa84 100644 --- a/windows/src/Makefile +++ b/windows/src/Makefile @@ -193,6 +193,11 @@ test-uiaccess: # * tar must be on path # +!ifndef COVBUILD +test-coverity: + echo Set variable COVBUILD to covbuild.exe + exit 1 +!else test-coverity: cd $(ROOT)\src if exist cov-int rd /s/q cov-int @@ -218,6 +223,7 @@ test-coverity-internal: $(MAKE) build cd $(ROOT)\src\engine\mcompile $(MAKE) build +!endif # Build a release diff --git a/windows/src/developer/kmcmpdll/Compiler.cpp b/windows/src/developer/kmcmpdll/Compiler.cpp index a5262b5c67..4853fcd7e4 100644 --- a/windows/src/developer/kmcmpdll/Compiler.cpp +++ b/windows/src/developer/kmcmpdll/Compiler.cpp @@ -97,7 +97,7 @@ BOOL IsSameToken(PWSTR *p, PWSTR token); DWORD GetRHS(PFILE_KEYBOARD fk, PWSTR p, PWSTR buf, int bufsize, int offset, int IsUnicode); PWSTR GetDelimitedString(PWSTR *p, PWSTR Delimiters, WORD Flags); DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int max, int offset, PWSTR *newp, int isVKey, - int isUnicode); + int isUnicode); int GetGroupNum(PFILE_KEYBOARD fk, PWSTR p); int LineTokenType(PWSTR *str); @@ -141,44 +141,44 @@ BOOL IsValidKeyboardVersion(WCHAR *dpString); // I4140 HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble); const PWCHAR LineTokens[] = { - L"SVNBHBGMNSCCLLCMLB", L"store", L"VERSION ", L"NAME ", - L"BITMAP ", L"HOTKEY ", L"begin", L"group", L"match", L"nomatch", - L"SHIFT FREES CAPS", L"CAPS ON ONLY", L"CAPS ALWAYS OFF", - L"LANGUAGE ", L"LAYOUT ", L"COPYRIGHT ", L"MESSAGE ", L"LANGUAGENAME ", - L"BITMAPS " }; + L"SVNBHBGMNSCCLLCMLB", L"store", L"VERSION ", L"NAME ", + L"BITMAP ", L"HOTKEY ", L"begin", L"group", L"match", L"nomatch", + L"SHIFT FREES CAPS", L"CAPS ON ONLY", L"CAPS ALWAYS OFF", + L"LANGUAGE ", L"LAYOUT ", L"COPYRIGHT ", L"MESSAGE ", L"LANGUAGENAME ", + L"BITMAPS " }; #define SSN__PREFIX L"&" -const PWCHAR StoreTokens[TSS__MAX+2] = { - L"", - SSN__PREFIX L"BITMAP", - SSN__PREFIX L"COPYRIGHT", - SSN__PREFIX L"HOTKEY", - SSN__PREFIX L"LANGUAGE", - SSN__PREFIX L"LAYOUT", - SSN__PREFIX L"MESSAGE", - SSN__PREFIX L"NAME", - SSN__PREFIX L"VERSION", - SSN__PREFIX L"CAPSONONLY", - SSN__PREFIX L"CAPSALWAYSOFF", - SSN__PREFIX L"SHIFTFREESCAPS", - SSN__PREFIX L"LANGUAGENAME", - L"", - L"", - SSN__PREFIX L"ETHNOLOGUECODE", - L"", - SSN__PREFIX L"MNEMONICLAYOUT", - SSN__PREFIX L"INCLUDECODES", - SSN__PREFIX L"OLDCHARPOSMATCHING", - L"", - L"", - L"", - L"", - SSN__PREFIX L"VISUALKEYBOARD", - SSN__PREFIX L"KMW_RTL", - SSN__PREFIX L"KMW_HELPFILE", - SSN__PREFIX L"KMW_HELPTEXT", - SSN__PREFIX L"KMW_EMBEDJS", +const PWCHAR StoreTokens[TSS__MAX + 2] = { + L"", + SSN__PREFIX L"BITMAP", + SSN__PREFIX L"COPYRIGHT", + SSN__PREFIX L"HOTKEY", + SSN__PREFIX L"LANGUAGE", + SSN__PREFIX L"LAYOUT", + SSN__PREFIX L"MESSAGE", + SSN__PREFIX L"NAME", + SSN__PREFIX L"VERSION", + SSN__PREFIX L"CAPSONONLY", + SSN__PREFIX L"CAPSALWAYSOFF", + SSN__PREFIX L"SHIFTFREESCAPS", + SSN__PREFIX L"LANGUAGENAME", + L"", + L"", + SSN__PREFIX L"ETHNOLOGUECODE", + L"", + SSN__PREFIX L"MNEMONICLAYOUT", + SSN__PREFIX L"INCLUDECODES", + SSN__PREFIX L"OLDCHARPOSMATCHING", + L"", + L"", + L"", + L"", + SSN__PREFIX L"VISUALKEYBOARD", + SSN__PREFIX L"KMW_RTL", + SSN__PREFIX L"KMW_HELPFILE", + SSN__PREFIX L"KMW_HELPTEXT", + SSN__PREFIX L"KMW_EMBEDJS", SSN__PREFIX L"WINDOWSLANGUAGES", L"", SSN__PREFIX L"PLATFORM", // read only // I3430 @@ -187,9 +187,9 @@ const PWCHAR StoreTokens[TSS__MAX+2] = { L"", // I3438 SSN__PREFIX L"LAYOUTFILE", // I3483 SSN__PREFIX L"KEYBOARDVERSION", // I4140 - SSN__PREFIX L"KMW_EMBEDCSS", + SSN__PREFIX L"KMW_EMBEDCSS", SSN__PREFIX L"TARGETS", // I4504 - NULL + NULL }; HINSTANCE g_hInstance; @@ -198,7 +198,7 @@ int currentLine = 0, nErrors = 0; char CompileDir[MAX_PATH]; int ErrChr; char ErrExtra[256]; -BOOL FSaveDebug, FCompilerWarningsAsErrors, FWarnDeprecatedCode; // I4865 // I4866 +BOOL FSaveDebug, FCompilerWarningsAsErrors, FWarnDeprecatedCode; // I4865 // I4866 BOOL FOldCharPosMatching = FALSE, FMnemonicLayout = FALSE; NamedCodeConstants *CodeConstants = NULL; @@ -212,346 +212,342 @@ int CompileTarget; BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved) { - if(fdwReason == DLL_PROCESS_ATTACH) g_hInstance = hinst; - return TRUE; + if (fdwReason == DLL_PROCESS_ATTACH) g_hInstance = hinst; + return TRUE; } PWSTR strtowstr(PSTR in) { - PWSTR result; - size_t len; + PWSTR result; + size_t len; - mbstowcs_s(&len, NULL, 0, in, strlen(in)); // I3481 - result = new WCHAR[len+1]; - mbstowcs_s(&len, result, len+1, in, strlen(in)); // I3481 // I3641 - result[len] = 0; - return result; + mbstowcs_s(&len, NULL, 0, in, strlen(in)); // I3481 + result = new WCHAR[len + 1]; + mbstowcs_s(&len, result, len + 1, in, strlen(in)); // I3481 // I3641 + result[len] = 0; + return result; } PSTR wstrtostr(PWSTR in) { - PSTR result; - size_t len; + PSTR result; + size_t len; - wcstombs_s(&len, NULL, 0, in, wcslen(in)); // I3481 - result = new CHAR[len+1]; - wcstombs_s(&len, result, len+1, in, wcslen(in)); // I3481 // I3641 - result[len] = 0; - return result; + wcstombs_s(&len, NULL, 0, in, wcslen(in)); // I3481 + result = new CHAR[len + 1]; + wcstombs_s(&len, result, len + 1, in, wcslen(in)); // I3481 // I3641 + result[len] = 0; + return result; } BOOL AddCompileString(LPSTR buf) { - SetLastError(0); - (*msgproc)(currentLine+1, CWARN_Info, buf); - return FALSE; + SetLastError(0); + (*msgproc)(currentLine + 1, CWARN_Info, buf); + return FALSE; } BOOL AddCompileMessage(DWORD msg) { - char szText[SZMAX_ERRORTEXT+1+280]; + char szText[SZMAX_ERRORTEXT + 1 + 280]; - SetLastError(0); - if(msg & CERR_MEMORY) - { - lstrcpy(szText, "Fatal Error: Out of Memory"); - (*msgproc)(currentLine+1, msg, szText); - nErrors++; - return TRUE; - } + SetLastError(0); + if (msg & CERR_MEMORY) + { + lstrcpy(szText, "Fatal Error: Out of Memory"); + (*msgproc)(currentLine + 1, msg, szText); + nErrors++; + return TRUE; + } - if(msg & CERR_FATAL) - { - LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); - (*msgproc)(currentLine+1, msg, szText); - nErrors++; - return TRUE; - } + if (msg & CERR_FATAL) + { + LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); + (*msgproc)(currentLine + 1, msg, szText); + nErrors++; + return TRUE; + } - if(msg & CERR_ERROR) nErrors++; - LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); - if(ErrChr > 0) - wsprintf(strchr(szText, 0), " chr:%d", ErrChr); - if(*ErrExtra) - wsprintf(strchr(szText, 0), " extra:%s", ErrExtra); + if (msg & CERR_ERROR) nErrors++; + LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); + if (ErrChr > 0) + wsprintf(strchr(szText, 0), " chr:%d", ErrChr); + if (*ErrExtra) + wsprintf(strchr(szText, 0), " extra:%s", ErrExtra); - ErrChr = 0; *ErrExtra = 0; + ErrChr = 0; *ErrExtra = 0; - if(!(*msgproc)(currentLine, msg, szText)) return TRUE; + if (!(*msgproc)(currentLine, msg, szText)) return TRUE; - return FALSE; + return FALSE; } extern "C" BOOL __declspec(dllexport) CompileKeyboardFile(PSTR pszInfile, PSTR pszOutfile, BOOL ASaveDebug, BOOL ACompilerWarningsAsErrors, BOOL AWarnDeprecatedCode, CompilerMessageProc pMsgProc) // I4865 // I4866 { - HANDLE hInfile = INVALID_HANDLE_VALUE, hOutfile = INVALID_HANDLE_VALUE; - BOOL err; - DWORD len; - char str[260]; + HANDLE hInfile = INVALID_HANDLE_VALUE, hOutfile = INVALID_HANDLE_VALUE; + BOOL err; + DWORD len; + char str[260]; - FSaveDebug = ASaveDebug; + FSaveDebug = ASaveDebug; FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 FWarnDeprecatedCode = AWarnDeprecatedCode; // I4866 CompileTarget = CKF_KEYMAN; - if(!pMsgProc) SetError(CERR_BadCallParams); + if (!pMsgProc || !pszInfile || !pszOutfile) SetError(CERR_BadCallParams); - PSTR p; - if(p = strrchr(pszInfile, '\\')) - { - strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p-pszInfile+1)); // I3481 - CompileDir[(INT_PTR)(p-pszInfile+1)] = 0; - } - else - CompileDir[0] = 0; + PSTR p; + if (p = strrchr(pszInfile, '\\')) + { + strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p - pszInfile + 1)); // I3481 + CompileDir[(INT_PTR)(p - pszInfile + 1)] = 0; + } + else + CompileDir[0] = 0; - msgproc = pMsgProc; - currentLine = 0; - nErrors = 0; + msgproc = pMsgProc; + currentLine = 0; + nErrors = 0; - if(!pszInfile || !pszOutfile) SetError(CERR_BadCallParams); + hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); - hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); + // Transfer the file to a memory stream for processing UTF-8 or ANSI to UTF-16? + // What about really large files? Transfer to a temp file... - // Transfer the file to a memory stream for processing UTF-8 or ANSI to UTF-16? - // What about really large files? Transfer to a temp file... - - if(!ReadFile(hInfile, str, 3, &len, NULL)) - { - CloseHandle(hInfile); - return CERR_CannotReadInfile; - } - SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); - if(str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) - hInfile = UTF16TempFromUTF8(hInfile, TRUE); - else if(str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) - SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); - else - hInfile = UTF16TempFromUTF8(hInfile, FALSE); // Will fall back to ansi for invalid UTF-8 - if(hInfile == INVALID_HANDLE_VALUE) // I3228 // I3510 + if (!ReadFile(hInfile, str, 3, &len, NULL)) + { + CloseHandle(hInfile); + return CERR_CannotReadInfile; + } + SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); + if (str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) + hInfile = UTF16TempFromUTF8(hInfile, TRUE); + else if (str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) + SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); + else + hInfile = UTF16TempFromUTF8(hInfile, FALSE); // Will fall back to ansi for invalid UTF-8 + if (hInfile == INVALID_HANDLE_VALUE) // I3228 // I3510 { return CERR_CannotCreateTempfile; } - hOutfile = CreateFileA(pszOutfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - if(hOutfile == INVALID_HANDLE_VALUE) SetError(CERR_CannotCreateOutfile); + hOutfile = CreateFileA(pszOutfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if (hOutfile == INVALID_HANDLE_VALUE) SetError(CERR_CannotCreateOutfile); - DWORD msg; - FILE_KEYBOARD fk; - CodeConstants = new NamedCodeConstants; + DWORD msg; + FILE_KEYBOARD fk; + CodeConstants = new NamedCodeConstants; - err = CompileKeyboardHandle(hInfile, &fk); - if(err) - { - if((msg = WriteCompiledKeyboard(&fk, hOutfile)) != CERR_None) - AddCompileMessage(msg); - } - else - AddCompileMessage(CERR_InvalidValue); + err = CompileKeyboardHandle(hInfile, &fk); + if (err) + { + if ((msg = WriteCompiledKeyboard(&fk, hOutfile)) != CERR_None) + AddCompileMessage(msg); + } + else + AddCompileMessage(CERR_InvalidValue); - CloseHandle(hInfile); - CloseHandle(hOutfile); + CloseHandle(hInfile); + CloseHandle(hOutfile); - delete CodeConstants; + delete CodeConstants; - if(nErrors > 0) - { - DeleteFile(pszOutfile); - return FALSE; - } + if (nErrors > 0) + { + DeleteFile(pszOutfile); + return FALSE; + } - return err; + return err; } extern "C" BOOL __declspec(dllexport) CompileKeyboardFileToBuffer(PSTR pszInfile, PFILE_KEYBOARD pfkBuffer, BOOL ACompilerWarningsAsErrors, BOOL AWarnDeprecatedCode, CompilerMessageProc pMsgProc, int Target) // I4865 // I4866 { - HANDLE hInfile = INVALID_HANDLE_VALUE; - BOOL err; - DWORD len; - char str[260]; + HANDLE hInfile = INVALID_HANDLE_VALUE; + BOOL err; + DWORD len; + char str[260]; - FSaveDebug = TRUE; // I3681 + FSaveDebug = TRUE; // I3681 FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 FWarnDeprecatedCode = AWarnDeprecatedCode; // I4866 CompileTarget = Target; - if(!pMsgProc) SetError(CERR_BadCallParams); + if (!pMsgProc || !pszInfile || !pfkBuffer) SetError(CERR_BadCallParams); - PSTR p; - if(p = strrchr(pszInfile, '\\')) - { - strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p-pszInfile+1)); // I3481 - CompileDir[(INT_PTR)(p-pszInfile+1)] = 0; - } - else - CompileDir[0] = 0; + PSTR p; + if (p = strrchr(pszInfile, '\\')) + { + strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p - pszInfile + 1)); // I3481 + CompileDir[(INT_PTR)(p - pszInfile + 1)] = 0; + } + else + CompileDir[0] = 0; - msgproc = pMsgProc; - currentLine = 0; - nErrors = 0; + msgproc = pMsgProc; + currentLine = 0; + nErrors = 0; - if(!pszInfile || !pfkBuffer) SetError(CERR_BadCallParams); + hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); - hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); + // Transfer the file to a memory stream for processing UTF-8 or ANSI to UTF-16? + // What about really large files? Transfer to a temp file... - // Transfer the file to a memory stream for processing UTF-8 or ANSI to UTF-16? - // What about really large files? Transfer to a temp file... + if (!ReadFile(hInfile, str, 3, &len, NULL)) + { + CloseHandle(hInfile); + return CERR_CannotReadInfile; + } + SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); + if (str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) + hInfile = UTF16TempFromUTF8(hInfile, TRUE); + else if (str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) + SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); + else + hInfile = UTF16TempFromUTF8(hInfile, FALSE); - if(!ReadFile(hInfile, str, 3, &len, NULL)) - { - CloseHandle(hInfile); - return CERR_CannotReadInfile; - } - SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); - if(str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) - hInfile = UTF16TempFromUTF8(hInfile, TRUE); - else if(str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) - SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); - else - hInfile = UTF16TempFromUTF8(hInfile, FALSE); + CodeConstants = new NamedCodeConstants; + err = CompileKeyboardHandle(hInfile, pfkBuffer); + delete CodeConstants; + CloseHandle(hInfile); - CodeConstants = new NamedCodeConstants; - err = CompileKeyboardHandle(hInfile, pfkBuffer); - delete CodeConstants; - CloseHandle(hInfile); + if (nErrors > 0) + return FALSE; - if(nErrors > 0) - return FALSE; - - return err; + return err; } void GetVersionInfo(DWORD *VersionMajor, DWORD *VersionMinor) { - HRSRC hres = FindResource(0, MAKEINTRESOURCE(1), RT_VERSION); - if(hres) - { - HGLOBAL hmem = LoadResource(0, hres); - PSTR buf = (PSTR) LockResource(hmem); - *VersionMajor = *((PDWORD) &buf[0x30]); - *VersionMinor = *((PDWORD) &buf[0x34]); - } + HRSRC hres = FindResource(0, MAKEINTRESOURCE(1), RT_VERSION); + if (hres) + { + HGLOBAL hmem = LoadResource(0, hres); + PSTR buf = (PSTR)LockResource(hmem); + *VersionMajor = *((PDWORD)&buf[0x30]); + *VersionMinor = *((PDWORD)&buf[0x34]); + } } BOOL CompileKeyboardHandle(HANDLE hInfile, PFILE_KEYBOARD fk) { - PWSTR str, p; + PWSTR str, p; - DWORD msg; + DWORD msg; - FMnemonicLayout = FALSE; + FMnemonicLayout = FALSE; if (!fk) { SetError(CERR_SomewhereIGotItWrong); } - str = new WCHAR[LINESIZE]; + str = new WCHAR[LINESIZE]; if (!str) { SetError(CERR_CannotAllocateMemory); } - fk->KeyboardID = 0; - fk->version = 0; - fk->dpStoreArray = NULL; - fk->dpGroupArray = NULL; - fk->cxStoreArray = 0; - fk->cxGroupArray = 0; - fk->StartGroup[0] = fk->StartGroup[1] = -1; - fk->szName[0] = 0; - fk->szCopyright[0] = 0; - fk->dwFlags = KF_AUTOMATICVERSION; - fk->currentGroup = 0xFFFFFFFF; - fk->currentStore = 0; - fk->cxDeadKeyArray = 0; - fk->dpDeadKeyArray = NULL; + fk->KeyboardID = 0; + fk->version = 0; + fk->dpStoreArray = NULL; + fk->dpGroupArray = NULL; + fk->cxStoreArray = 0; + fk->cxGroupArray = 0; + fk->StartGroup[0] = fk->StartGroup[1] = -1; + fk->szName[0] = 0; + fk->szCopyright[0] = 0; + fk->dwFlags = KF_AUTOMATICVERSION; + fk->currentGroup = 0xFFFFFFFF; + fk->currentStore = 0; + fk->cxDeadKeyArray = 0; + fk->dpDeadKeyArray = NULL; fk->cxVKDictionary = 0; // I3438 fk->dpVKDictionary = NULL; // I3438 /* fk->szMessage[0] = 0; - fk->szLanguageName[0] = 0;*/ - fk->dwBitmapSize = 0; - fk->dwHotKey = 0; + fk->szLanguageName[0] = 0;*/ + fk->dwBitmapSize = 0; + fk->dwHotKey = 0; - /* Add a store for the Keyman 6.0 copyright information string */ + /* Add a store for the Keyman 6.0 copyright information string */ - DWORD vmajor, vminor; - GetVersionInfo(&vmajor, &vminor); - //char buf[256]; - swprintf(str, LINESIZE, L"Created with Keyman Developer version %d.%d.%d.%d", HIWORD(vmajor), - LOWORD(vmajor), HIWORD(vminor), LOWORD(vminor)); // I3481 + DWORD vmajor, vminor; + GetVersionInfo(&vmajor, &vminor); + //char buf[256]; + swprintf(str, LINESIZE, L"Created with Keyman Developer version %d.%d.%d.%d", HIWORD(vmajor), + LOWORD(vmajor), HIWORD(vminor), LOWORD(vminor)); // I3481 - //PWSTR pw = strtowstr(buf); - AddStore(fk, TSS_KEYMANCOPYRIGHT, str); - //delete pw; +//PWSTR pw = strtowstr(buf); + AddStore(fk, TSS_KEYMANCOPYRIGHT, str); + //delete pw; - /* Add a system store for the Keyman edition number */ + /* Add a system store for the Keyman edition number */ - swprintf(str, LINESIZE, L"%d", 0); // I3481 - AddStore(fk, TSS_CUSTOMKEYMANEDITION, str); - PWSTR tbuf = strtowstr((char*) "Keyman"); - AddStore(fk, TSS_CUSTOMKEYMANEDITIONNAME, tbuf); - delete tbuf; + swprintf(str, LINESIZE, L"%d", 0); // I3481 + AddStore(fk, TSS_CUSTOMKEYMANEDITION, str); + PWSTR tbuf = strtowstr((char*) "Keyman"); + AddStore(fk, TSS_CUSTOMKEYMANEDITIONNAME, tbuf); + delete tbuf; - // must preprocess for group and store names -> this isn't really necessary, but never mind! - while((msg = ReadLine(hInfile, str, TRUE)) == CERR_None) + // must preprocess for group and store names -> this isn't really necessary, but never mind! + while ((msg = ReadLine(hInfile, str, TRUE)) == CERR_None) + { + if (GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); + p = str; + switch (LineTokenType(&p)) { - if(GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); - p = str; - switch(LineTokenType(&p)) - { - case T_VERSION: - *(p+4) = 0; - if((msg = AddStore(fk, TSS_VERSION, p)) != CERR_None) SetError(msg); - break; + case T_VERSION: + *(p + 4) = 0; + if ((msg = AddStore(fk, TSS_VERSION, p)) != CERR_None) SetError(msg); + break; - case T_GROUP: - if((msg = ProcessGroupLine(fk, p)) != CERR_None) SetError(msg); - break; + case T_GROUP: + if ((msg = ProcessGroupLine(fk, p)) != CERR_None) SetError(msg); + break; - case T_STORE: - if((msg = ProcessStoreLine(fk, p)) != CERR_None) SetError(msg); - break; + case T_STORE: + if ((msg = ProcessStoreLine(fk, p)) != CERR_None) SetError(msg); + break; - default: - break; - } - } + default: + break; + } + } - if(msg != CERR_EndOfFile) SetError(msg); + if (msg != CERR_EndOfFile) SetError(msg); - SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); - currentLine = 0; + SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); + currentLine = 0; - /* Reindex the list of codeconstants after stores added */ + /* Reindex the list of codeconstants after stores added */ - CodeConstants->reindex(); + CodeConstants->reindex(); - /* ReadLine will automatically skip over $Keyman lines, and parse wrapped lines */ - while((msg = ReadLine(hInfile, str, FALSE)) == CERR_None) - { - if(GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); - msg = ParseLine(fk, str); - if(msg != CERR_None) SetError(msg); - } + /* ReadLine will automatically skip over $Keyman lines, and parse wrapped lines */ + while ((msg = ReadLine(hInfile, str, FALSE)) == CERR_None) + { + if (GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); + msg = ParseLine(fk, str); + if (msg != CERR_None) SetError(msg); + } - if(msg != CERR_EndOfFile) SetError(msg); + if (msg != CERR_EndOfFile) SetError(msg); - ProcessGroupFinish(fk); + ProcessGroupFinish(fk); - if(FSaveDebug) RecordDeadkeyNames(fk); + if (FSaveDebug) RecordDeadkeyNames(fk); - /* Add the compiler version as a system store */ - if((msg = AddCompilerVersionStore(fk)) != CERR_None) SetError(msg); + /* Add the compiler version as a system store */ + if ((msg = AddCompilerVersionStore(fk)) != CERR_None) SetError(msg); - if((msg = BuildVKDictionary(fk)) != CERR_None) SetError(msg); // I3438 + if ((msg = BuildVKDictionary(fk)) != CERR_None) SetError(msg); // I3438 - delete str; + delete str; if (!CheckKeyboardFinalVersion(fk)) { return FALSE; @@ -565,37 +561,37 @@ BOOL CompileKeyboardHandle(HANDLE hInfile, PFILE_KEYBOARD fk) DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PWSTR p) { - WCHAR tstr[128]; - PWSTR q, pp; - int BeginMode; - DWORD msg; + WCHAR tstr[128]; + PWSTR q, pp; + int BeginMode; + DWORD msg; - pp = p; + pp = p; - q = wcschr(p, '>'); - if(!q) return CERR_NoTokensFound; + q = wcschr(p, '>'); + if (!q) return CERR_NoTokensFound; - while(iswspace(*p)) p++; - if(_wcsnicmp(p, L"unicode", 7) == 0) BeginMode = BEGIN_UNICODE; - else if(_wcsnicmp(p, L"ansi", 4) == 0) BeginMode = BEGIN_ANSI; - else if(*p != '>') return CERR_InvalidToken; - else BeginMode = BEGIN_ANSI; + while (iswspace(*p)) p++; + if (_wcsnicmp(p, L"unicode", 7) == 0) BeginMode = BEGIN_UNICODE; + else if (_wcsnicmp(p, L"ansi", 4) == 0) BeginMode = BEGIN_ANSI; + else if (*p != '>') return CERR_InvalidToken; + else BeginMode = BEGIN_ANSI; - if((msg = GetRHS(fk, p, tstr, 80, (int)(INT_PTR)(p-pp), FALSE)) != CERR_None) return msg; + if ((msg = GetRHS(fk, p, tstr, 80, (int)(INT_PTR)(p - pp), FALSE)) != CERR_None) return msg; - if(tstr[0] != UC_SENTINEL || tstr[1] != CODE_USE) return CERR_InvalidBegin; + if (tstr[0] != UC_SENTINEL || tstr[1] != CODE_USE) return CERR_InvalidBegin; - fk->StartGroup[BeginMode] = tstr[2] - 1; - //mcd-03-01-2000: removed the secondary group idea; this was undocumented and - //is not supported under Keyman 5.0: ugly!! - //if(tstr[3] == UC_SENTINEL && tstr[4] == CODE_USE) fk->StartGroup[1] = tstr[5] - 1; - if(tstr[3] != 0) return CERR_InvalidToken; + fk->StartGroup[BeginMode] = tstr[2] - 1; + //mcd-03-01-2000: removed the secondary group idea; this was undocumented and + //is not supported under Keyman 5.0: ugly!! + //if(tstr[3] == UC_SENTINEL && tstr[4] == CODE_USE) fk->StartGroup[1] = tstr[5] - 1; + if (tstr[3] != 0) return CERR_InvalidToken; - if(FSaveDebug) - /* Record a system store for the line number of the begin statement */ - AddDebugStore(fk, BeginMode == BEGIN_UNICODE ? DEBUGSTORE_BEGIN L"Unicode" : DEBUGSTORE_BEGIN L"ANSI"); + if (FSaveDebug) + /* Record a system store for the line number of the begin statement */ + AddDebugStore(fk, BeginMode == BEGIN_UNICODE ? DEBUGSTORE_BEGIN L"Unicode" : DEBUGSTORE_BEGIN L"ANSI"); - return CERR_None; + return CERR_None; } DWORD ValidateMatchNomatchOutput(PWSTR p) { @@ -615,181 +611,147 @@ DWORD ValidateMatchNomatchOutput(PWSTR p) { DWORD ParseLine(PFILE_KEYBOARD fk, PWSTR str) { - PWSTR p, q, pp; - PFILE_GROUP gp; - DWORD msg; - int IsUnicode = TRUE; // For NOW! + PWSTR p, q, pp; + PFILE_GROUP gp; + DWORD msg; + int IsUnicode = TRUE; // For NOW! - p = str; - pp = str; + p = str; + pp = str; - switch(LineTokenType(&p)) + switch (LineTokenType(&p)) + { + case T_BLANK: + case T_COMMENT: + break; // Ignore the line + case T_VERSION: + case T_STORE: + break; // The line has already been processed + + case T_BEGIN: + // after a begin can be "Unicode" or "ANSI" or nothing (=ANSI) + if ((msg = ProcessBeginLine(fk, p)) != CERR_None) return msg; + break; + + case T_GROUP: + if (fk->currentGroup == 0xFFFFFFFF) fk->currentGroup = 0; + else { - case T_BLANK: - case T_COMMENT: - break; // Ignore the line - case T_VERSION: - case T_STORE: - break; // The line has already been processed + if ((msg = ProcessGroupFinish(fk)) != CERR_None) return msg; // finish off previous group first? + fk->currentGroup++; + } + // if( (err = ProcessGroupLine( fk, p )) != CERR_None ) return err; + break; - case T_BEGIN: - // after a begin can be "Unicode" or "ANSI" or nothing (=ANSI) - if((msg = ProcessBeginLine(fk, p)) != CERR_None) return msg; - break; - - case T_GROUP: - if(fk->currentGroup == 0xFFFFFFFF) fk->currentGroup = 0; - else - { - if((msg = ProcessGroupFinish(fk)) != CERR_None) return msg; // finish off previous group first? - fk->currentGroup++; - } -// if( (err = ProcessGroupLine( fk, p )) != CERR_None ) return err; - break; - - case T_NAME: + case T_NAME: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if( !q ) return CERR_InvalidName; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidName; - if((msg = AddStore(fk, TSS_NAME, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_NAME, q)) != CERR_None) return msg; + break; - case T_COPYRIGHT: + case T_COPYRIGHT: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if(!q) return CERR_InvalidCopyright; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidCopyright; - if((msg = AddStore(fk, TSS_COPYRIGHT, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_COPYRIGHT, q)) != CERR_None) return msg; + break; case T_MESSAGE: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if(!q) return CERR_InvalidMessage; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidMessage; - if((msg = AddStore(fk, TSS_MESSAGE, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_MESSAGE, q)) != CERR_None) return msg; + break; - case T_LANGUAGENAME: + case T_LANGUAGENAME: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if(!q) return CERR_InvalidLanguageName; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidLanguageName; - if((msg = AddStore(fk, TSS_LANGUAGENAME, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_LANGUAGENAME, q)) != CERR_None) return msg; + break; - case T_LANGUAGE: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - q = wcstok_s(p, L"\n", &tokcontext); // I3481 - if((msg = AddStore(fk, TSS_LANGUAGE, q)) != CERR_None) return msg; - break; - } - case T_LAYOUT: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - q = wcstok_s(p, L"\n", &tokcontext); // I3481 - if((msg = AddStore(fk, TSS_LAYOUT, q)) != CERR_None) return msg; - break; - } - case T_CAPSOFF: + case T_LANGUAGE: + { WarnDeprecatedHeader(); // I4866 - if((msg = AddStore(fk, TSS_CAPSALWAYSOFF, L"1")) != CERR_None) return msg; - break; - - case T_CAPSON: + wchar_t *tokcontext = NULL; + q = wcstok_s(p, L"\n", &tokcontext); // I3481 + if ((msg = AddStore(fk, TSS_LANGUAGE, q)) != CERR_None) return msg; + break; + } + case T_LAYOUT: + { WarnDeprecatedHeader(); // I4866 - if((msg = AddStore(fk, TSS_CAPSONONLY, L"1")) != CERR_None) return msg; - break; - - case T_SHIFT: + wchar_t *tokcontext = NULL; + q = wcstok_s(p, L"\n", &tokcontext); // I3481 + if ((msg = AddStore(fk, TSS_LAYOUT, q)) != CERR_None) return msg; + break; + } + case T_CAPSOFF: WarnDeprecatedHeader(); // I4866 - if((msg = AddStore(fk, TSS_SHIFTFREESCAPS, L"1")) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_CAPSALWAYSOFF, L"1")) != CERR_None) return msg; + break; - case T_HOTKEY: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - if((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_CodeInvalidInThisSection; // I3481 - if((msg = AddStore(fk, TSS_HOTKEY, q)) != CERR_None) return msg; - break; + case T_CAPSON: + WarnDeprecatedHeader(); // I4866 + if ((msg = AddStore(fk, TSS_CAPSONONLY, L"1")) != CERR_None) return msg; + break; + + case T_SHIFT: + WarnDeprecatedHeader(); // I4866 + if ((msg = AddStore(fk, TSS_SHIFTFREESCAPS, L"1")) != CERR_None) return msg; + break; + + case T_HOTKEY: + { + WarnDeprecatedHeader(); // I4866 + wchar_t *tokcontext = NULL; + if ((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_CodeInvalidInThisSection; // I3481 + if ((msg = AddStore(fk, TSS_HOTKEY, q)) != CERR_None) return msg; + break; + } + case T_BITMAP: + { + WarnDeprecatedHeader(); // I4866 + wchar_t *tokcontext = NULL; + if ((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + + while (iswspace(*q)) q++; + if (*q == '"') { + p = q; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidBitmapLine; } - case T_BITMAP: + + if ((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; + break; + } + case T_BITMAPS: + { + WarnDeprecatedHeader(); // I4866 + wchar_t *tokcontext = NULL; + AddWarning(CWARN_BitmapNotUsed); + + if ((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + if (wcschr(q, ',')) *wcschr(q, ',') = 0; + if ((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; + + break; + } + case T_KEYTOKEY: // A rule + if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + if ((msg = ProcessKeyLine(fk, p, IsUnicode)) != CERR_None) return msg; + break; + + case T_MATCH: + if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - if((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 - - while(iswspace(*q)) q++; - if(*q == '"') { p = q; q = GetDelimitedString(&p, L"\"\"", 0); } - - if((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; - break; - } - case T_BITMAPS: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - AddWarning(CWARN_BitmapNotUsed); - - if((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 - if(wcschr(q, ',')) *wcschr(q, ',') = 0; - if((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; - - break; - } - case T_KEYTOKEY: // A rule - if(fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; - if((msg = ProcessKeyLine(fk, p, IsUnicode)) != CERR_None) return msg; - break; - - case T_MATCH: - if(fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; - { - PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; - if((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(p-pp), IsUnicode)) != CERR_None) - { - delete buf; - return msg; - } - - if ((msg = ValidateMatchNomatchOutput(buf)) != CERR_None) { - delete buf; - return msg; - } - - gp = &fk->dpGroupArray[fk->currentGroup]; - - gp->dpMatch = new WCHAR[wcslen(buf) + 1]; - wcscpy_s(gp->dpMatch, wcslen(buf)+1, buf); // I3481 - - delete buf; - - if(FSaveDebug) - { - WCHAR tstr[128]; - //char buf[256]; - //swprintf(tstr, "%d", fk->currentGroup); - /* Record a system store for the line number of the begin statement */ - //wcscpy(tstr, DEBUGSTORE_MATCH); - - //wcscat(tstr, pw); - - swprintf(tstr, _countof(tstr), L"%s%d %s", DEBUGSTORE_MATCH, fk->currentGroup, gp->szName); // I3481 - AddDebugStore(fk, tstr); - } - } - break; - - case T_NOMATCH: - if(fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; - { - PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; - if((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE, (int)(INT_PTR)(p-pp), IsUnicode)) != CERR_None) + PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(p - pp), IsUnicode)) != CERR_None) { delete buf; return msg; @@ -800,72 +762,110 @@ DWORD ParseLine(PFILE_KEYBOARD fk, PWSTR str) return msg; } - gp = &fk->dpGroupArray[fk->currentGroup]; + gp = &fk->dpGroupArray[fk->currentGroup]; - gp->dpNoMatch = new WCHAR[wcslen(buf) + 1]; - wcscpy_s(gp->dpNoMatch, wcslen(buf)+1, buf); // I3481 + gp->dpMatch = new WCHAR[wcslen(buf) + 1]; + wcscpy_s(gp->dpMatch, wcslen(buf) + 1, buf); // I3481 - delete buf; + delete buf; - if(FSaveDebug) - { - WCHAR tstr[128]; - /* Record a system store for the line number of the begin statement */ - swprintf(tstr, _countof(tstr), L"%s%d %s", DEBUGSTORE_NOMATCH, fk->currentGroup, gp->szName); // I3481 - AddDebugStore(fk, tstr); - } - } - break; + if (FSaveDebug) + { + WCHAR tstr[128]; + //char buf[256]; + //swprintf(tstr, "%d", fk->currentGroup); + /* Record a system store for the line number of the begin statement */ + //wcscpy(tstr, DEBUGSTORE_MATCH); - default: - return CERR_InvalidToken; - } + //wcscat(tstr, pw); - return CERR_None; + swprintf(tstr, _countof(tstr), L"%ls%d %ls", DEBUGSTORE_MATCH, (int) fk->currentGroup, gp->szName); // I3481 + AddDebugStore(fk, tstr); + } + } + break; + + case T_NOMATCH: + if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + { + PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE, (int)(INT_PTR)(p - pp), IsUnicode)) != CERR_None) + { + delete[] buf; + return msg; + } + + if ((msg = ValidateMatchNomatchOutput(buf)) != CERR_None) { + delete[] buf; + return msg; + } + + gp = &fk->dpGroupArray[fk->currentGroup]; + + gp->dpNoMatch = new WCHAR[wcslen(buf) + 1]; + wcscpy_s(gp->dpNoMatch, wcslen(buf) + 1, buf); // I3481 + + delete[] buf; + + if (FSaveDebug) + { + WCHAR tstr[128]; + /* Record a system store for the line number of the begin statement */ + swprintf(tstr, _countof(tstr), L"%ls%d %ls", DEBUGSTORE_NOMATCH, fk->currentGroup, gp->szName); // I3481 + AddDebugStore(fk, tstr); + } + } + break; + + default: + return CERR_InvalidToken; + } + + return CERR_None; } //********************************************************************************************************************** DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PWSTR p) { - PFILE_GROUP gp; - PWSTR q; + PFILE_GROUP gp; + PWSTR q; - gp = new FILE_GROUP[fk->cxGroupArray + 1]; - if(!gp) return CERR_CannotAllocateMemory; + gp = new FILE_GROUP[fk->cxGroupArray + 1]; + if (!gp) return CERR_CannotAllocateMemory; - if(fk->dpGroupArray) - { - memcpy(gp, fk->dpGroupArray, sizeof(FILE_GROUP) * fk->cxGroupArray); - delete fk->dpGroupArray; - } + if (fk->dpGroupArray) + { + memcpy(gp, fk->dpGroupArray, sizeof(FILE_GROUP) * fk->cxGroupArray); + delete fk->dpGroupArray; + } - fk->dpGroupArray = gp; - gp = &fk->dpGroupArray[fk->cxGroupArray]; - fk->cxGroupArray++; + fk->dpGroupArray = gp; + gp = &fk->dpGroupArray[fk->cxGroupArray]; + fk->cxGroupArray++; - gp->dpKeyArray = NULL; - gp->dpMatch = NULL; - gp->dpNoMatch = NULL; - gp->cxKeyArray = 0; + gp->dpKeyArray = NULL; + gp->dpMatch = NULL; + gp->dpNoMatch = NULL; + gp->cxKeyArray = 0; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q) return CERR_InvalidGroupLine; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q) return CERR_InvalidGroupLine; - gp->fUsingKeys = FALSE; - if(IsSameToken(&p, L"using") && IsSameToken(&p, L"keys")) gp->fUsingKeys = TRUE; + gp->fUsingKeys = FALSE; + if (IsSameToken(&p, L"using") && IsSameToken(&p, L"keys")) gp->fUsingKeys = TRUE; - safe_wcsncpy(gp->szName, q, SZMAX_GROUPNAME); + safe_wcsncpy(gp->szName, q, SZMAX_GROUPNAME); - if(FSaveDebug) - { - WCHAR tstr[128]; - /* Record a system store for the line number of the begin statement */ - swprintf(tstr, _countof(tstr), L"%s%d %s", DEBUGSTORE_GROUP, fk->cxGroupArray-1, gp->szName); // I3481 - AddDebugStore(fk, tstr); - } + if (FSaveDebug) + { + WCHAR tstr[128]; + /* Record a system store for the line number of the begin statement */ + swprintf(tstr, _countof(tstr), L"%ls%d %ls", DEBUGSTORE_GROUP, fk->cxGroupArray - 1, gp->szName); // I3481 + AddDebugStore(fk, tstr); + } - return CERR_None; + return CERR_None; } /* Following code lifted from syskbd.cpp and tweaked for compiler use. Todo: consolidate */ @@ -885,104 +885,104 @@ DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PWSTR p) WCHAR VKToChar(WORD keyCode, UINT shiftFlags) { - char shiftedDigit[] = ")!@#$%^&*("; - int n, Shift; + char shiftedDigit[] = ")!@#$%^&*("; + int n, Shift; - if(!(shiftFlags & ISVIRTUALKEY)) return keyCode; + if (!(shiftFlags & ISVIRTUALKEY)) return keyCode; - if(shiftFlags & (LCTRLFLAG|RCTRLFLAG|LALTFLAG|RALTFLAG)) return 0; + if (shiftFlags & (LCTRLFLAG | RCTRLFLAG | LALTFLAG | RALTFLAG)) return 0; - if(keyCode >= '0' && keyCode <= '9') - { - n = keyCode - '0'; - return ((shiftFlags & K_SHIFTFLAG) ? shiftedDigit[n] : keyCode); - } + if (keyCode >= '0' && keyCode <= '9') + { + n = keyCode - '0'; + return ((shiftFlags & K_SHIFTFLAG) ? shiftedDigit[n] : keyCode); + } - if(keyCode >= 'A' && keyCode <= 'Z') - { - Shift = (shiftFlags & K_SHIFTFLAG); - if(shiftFlags & (CAPITALFLAG)) Shift = !Shift; - return (Shift ? keyCode : keyCode + 32); - } + if (keyCode >= 'A' && keyCode <= 'Z') + { + Shift = (shiftFlags & K_SHIFTFLAG); + if (shiftFlags & (CAPITALFLAG)) Shift = !Shift; + return (Shift ? keyCode : keyCode + 32); + } - if(keyCode >= VK_NUMPAD0 && keyCode <= VK_NUMPAD9) - { - if(!(shiftFlags & NUMLOCKFLAG)) return 0; - return keyCode - (VK_NUMPAD0 - '0'); - } + if (keyCode >= VK_NUMPAD0 && keyCode <= VK_NUMPAD9) + { + if (!(shiftFlags & NUMLOCKFLAG)) return 0; + return keyCode - (VK_NUMPAD0 - '0'); + } - Shift = (shiftFlags & K_SHIFTFLAG); + Shift = (shiftFlags & K_SHIFTFLAG); - switch(keyCode) - { - case VK_ACCENT: - return Shift ? '~' : '`'; - case VK_HYPHEN: - return Shift ? '_' : '-'; - case VK_EQUAL: - return Shift ? '+' : '='; - case VK_BKSLASH: - return Shift ? '|' : 92; - case VK_LBRKT: - return Shift ? '{' : '['; - case VK_RBRKT: - return Shift ? '}' : ']'; - case VK_COLON: - return Shift ? ':' : ';'; - case VK_QUOTE: - return Shift ? '"' : 39; - case VK_COMMA: - return Shift ? '<' : ','; - case VK_PERIOD: - return Shift ? '>' : '.'; - case VK_SLASH: - return Shift ? '?' : '/'; - case VK_SPACE: - return ' '; - } - return 0; - //keyCode; + switch (keyCode) + { + case VK_ACCENT: + return Shift ? '~' : '`'; + case VK_HYPHEN: + return Shift ? '_' : '-'; + case VK_EQUAL: + return Shift ? '+' : '='; + case VK_BKSLASH: + return Shift ? '|' : 92; + case VK_LBRKT: + return Shift ? '{' : '['; + case VK_RBRKT: + return Shift ? '}' : ']'; + case VK_COLON: + return Shift ? ':' : ';'; + case VK_QUOTE: + return Shift ? '"' : 39; + case VK_COMMA: + return Shift ? '<' : ','; + case VK_PERIOD: + return Shift ? '>' : '.'; + case VK_SLASH: + return Shift ? '?' : '/'; + case VK_SPACE: + return ' '; + } + return 0; + //keyCode; } int cmpkeys(const void *key, const void *elem) { - PFILE_KEY akey, aelem; - int l1, l2; + PFILE_KEY akey, aelem; + int l1, l2; WCHAR char_key, char_elem; - akey = (PFILE_KEY)key; - aelem = (PFILE_KEY)elem; + akey = (PFILE_KEY)key; + aelem = (PFILE_KEY)elem; char_key = VKToChar(akey->Key, akey->ShiftFlags); char_elem = VKToChar(aelem->Key, aelem->ShiftFlags); - if(char_key == char_elem) //akey->Key == aelem->Key) + if (char_key == char_elem) //akey->Key == aelem->Key) + { + l1 = xstrlen(akey->dpContext); l2 = xstrlen(aelem->dpContext); + if (l1 == l2) { - l1 = xstrlen(akey->dpContext); l2 = xstrlen(aelem->dpContext); - if(l1 == l2) - { - if(akey->Line < aelem->Line) return -1; - if(akey->Line > aelem->Line) return 1; - return 0; - } - if(l1 < l2) return 1; - if(l1 > l2) return -1; - } - return(char_key - char_elem); // akey->Key - aelem->Key); + if (akey->Line < aelem->Line) return -1; + if (akey->Line > aelem->Line) return 1; + return 0; + } + if (l1 < l2) return 1; + if (l1 > l2) return -1; + } + return(char_key - char_elem); // akey->Key - aelem->Key); } DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) { - PFILE_GROUP gp; + PFILE_GROUP gp; - if(fk->currentGroup == 0xFFFFFFFF) return CERR_None; - // Just got to first group - so nothing to finish yet + if (fk->currentGroup == 0xFFFFFFFF) return CERR_None; + // Just got to first group - so nothing to finish yet - gp = &fk->dpGroupArray[fk->currentGroup]; + gp = &fk->dpGroupArray[fk->currentGroup]; - // Finish off the previous group stuff! - qsort(gp->dpKeyArray, gp->cxKeyArray, sizeof(FILE_KEY), cmpkeys); + // Finish off the previous group stuff! + qsort(gp->dpKeyArray, gp->cxKeyArray, sizeof(FILE_KEY), cmpkeys); - return CERR_None; - } + return CERR_None; +} /*************************************** * Store management @@ -990,35 +990,35 @@ DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PWSTR p) { - PWSTR q, pp; - PFILE_STORE sp; - //WCHAR temp[GLOBAL_BUFSIZE]; - DWORD msg; - int i = 0; + PWSTR q, pp; + PFILE_STORE sp; + //WCHAR temp[GLOBAL_BUFSIZE]; + DWORD msg; + int i = 0; - pp = p; + pp = p; - if((q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL)) == NULL) return CERR_InvalidStoreLine; + if ((q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL)) == NULL) return CERR_InvalidStoreLine; - if(*q == *SSN__PREFIX) - { - for(i = 0; StoreTokens[i]; i++) - if(!_wcsicmp(q, StoreTokens[i])) // I3481 - break; - if(!StoreTokens[i]) return CERR_InvalidSystemStore; - } + if (*q == *SSN__PREFIX) + { + for (i = 0; StoreTokens[i]; i++) + if (!_wcsicmp(q, StoreTokens[i])) // I3481 + break; + if (!StoreTokens[i]) return CERR_InvalidSystemStore; + } - sp = new FILE_STORE[fk->cxStoreArray+1]; - if(!sp) return CERR_CannotAllocateMemory; + sp = new FILE_STORE[fk->cxStoreArray + 1]; + if (!sp) return CERR_CannotAllocateMemory; - if(fk->dpStoreArray) - { - memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); - delete fk->dpStoreArray; - } + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete fk->dpStoreArray; + } - fk->dpStoreArray = sp; - sp = &fk->dpStoreArray[fk->cxStoreArray]; + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; sp->line = currentLine; sp->fIsOption = FALSE; @@ -1031,58 +1031,58 @@ DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PWSTR p) { PWCHAR temp = new WCHAR[GLOBAL_BUFSIZE]; - if((msg = GetXString(fk, p, L"c\n", temp, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(p-pp), &p, FALSE, TRUE)) != CERR_None) - { - delete temp; - return msg; - } + if ((msg = GetXString(fk, p, L"c\n", temp, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(p - pp), &p, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } - sp->dwSystemID = i; - sp->dpString = new WCHAR[wcslen(temp)+1]; - wcscpy_s(sp->dpString, wcslen(temp)+1, temp); // I3481 + sp->dwSystemID = i; + sp->dpString = new WCHAR[wcslen(temp) + 1]; + wcscpy_s(sp->dpString, wcslen(temp) + 1, temp); // I3481 - delete temp; - } + delete[] temp; + } - if(xstrlen(sp->dpString) == 1 && *sp->dpString != UC_SENTINEL && - sp->dwSystemID == 0 && (fk->version >= VERSION_60 || fk->version == 0)) - { + if (xstrlen(sp->dpString) == 1 && *sp->dpString != UC_SENTINEL && + sp->dwSystemID == 0 && (fk->version >= VERSION_60 || fk->version == 0)) + { // In this case, we want to change behaviour for older versioned keyboards so that // we don't mix up named character codes which weren't supported in 5.x VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); - // Add a single char store as a defined character constant - char *codename = wstrtostr(sp->szName); - if(Uni_IsSurrogate1(*sp->dpString)) + // Add a single char store as a defined character constant + char *codename = wstrtostr(sp->szName); + if (Uni_IsSurrogate1(*sp->dpString)) CodeConstants->AddCode(Uni_SurrogateToUTF32(sp->dpString[0], sp->dpString[1]), codename, fk->cxStoreArray); - else - CodeConstants->AddCode(sp->dpString[0], codename, fk->cxStoreArray); - delete codename; + else + CodeConstants->AddCode(sp->dpString[0], codename, fk->cxStoreArray); + delete[] codename; CodeConstants->reindex(); // has to be done after every character add due to possible use in another store. // I4982 - } + } - fk->cxStoreArray++; // increment now, because GetXString refers to stores + fk->cxStoreArray++; // increment now, because GetXString refers to stores - if(i > 0) - if((msg = ProcessSystemStore(fk, i, sp)) != CERR_None) return msg; + if (i > 0) + if ((msg = ProcessSystemStore(fk, i, sp)) != CERR_None) return msg; - return CERR_None; + return CERR_None; } DWORD AddStore(PFILE_KEYBOARD fk, DWORD SystemID, PWSTR str, DWORD *dwStoreID) { - PFILE_STORE sp; + PFILE_STORE sp; - sp = new FILE_STORE[fk->cxStoreArray+1]; - if(!sp) return CERR_CannotAllocateMemory; + sp = new FILE_STORE[fk->cxStoreArray + 1]; + if (!sp) return CERR_CannotAllocateMemory; - if(fk->dpStoreArray) - { - memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); - delete fk->dpStoreArray; - } + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete fk->dpStoreArray; + } - fk->dpStoreArray = sp; - sp = &fk->dpStoreArray[fk->cxStoreArray]; + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; sp->line = currentLine; sp->fIsOption = FALSE; // I3686 @@ -1091,211 +1091,211 @@ DWORD AddStore(PFILE_KEYBOARD fk, DWORD SystemID, PWSTR str, DWORD *dwStoreID) sp->fIsDebug = FALSE; sp->fIsCall = FALSE; - safe_wcsncpy(sp->szName, StoreTokens[SystemID], SZMAX_STORENAME); + safe_wcsncpy(sp->szName, StoreTokens[SystemID], SZMAX_STORENAME); - sp->dpString = new WCHAR[wcslen(str)+1]; - wcscpy_s(sp->dpString, wcslen(str)+1, str); // I3481 + sp->dpString = new WCHAR[wcslen(str) + 1]; + wcscpy_s(sp->dpString, wcslen(str) + 1, str); // I3481 - sp->dwSystemID = SystemID; + sp->dwSystemID = SystemID; - if(dwStoreID) *dwStoreID = fk->cxStoreArray; + if (dwStoreID) *dwStoreID = fk->cxStoreArray; fk->cxStoreArray++; - return ProcessSystemStore(fk, SystemID, sp); + return ProcessSystemStore(fk, SystemID, sp); } DWORD AddDebugStore(PFILE_KEYBOARD fk, PWSTR str) { - PFILE_STORE sp; - WCHAR tstr[16]; + PFILE_STORE sp; + WCHAR tstr[16]; - swprintf(tstr, _countof(tstr), L"%d", currentLine); // I3481 + swprintf(tstr, _countof(tstr), L"%d", currentLine); // I3481 - sp = new FILE_STORE[fk->cxStoreArray+1]; - if(!sp) return CERR_CannotAllocateMemory; + sp = new FILE_STORE[fk->cxStoreArray + 1]; + if (!sp) return CERR_CannotAllocateMemory; - if(fk->dpStoreArray) - { - memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); - delete[] fk->dpStoreArray; - } + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete[] fk->dpStoreArray; + } - fk->dpStoreArray = sp; - sp = &fk->dpStoreArray[fk->cxStoreArray]; + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; - safe_wcsncpy(sp->szName, str, SZMAX_STORENAME); + safe_wcsncpy(sp->szName, str, SZMAX_STORENAME); - sp->dpString = new WCHAR[wcslen(tstr)+1]; - wcscpy_s(sp->dpString, wcslen(tstr)+1, tstr); // I3481 + sp->dpString = new WCHAR[wcslen(tstr) + 1]; + wcscpy_s(sp->dpString, wcslen(tstr) + 1, tstr); // I3481 sp->line = 0; sp->fIsOption = FALSE; sp->fIsReserved = TRUE; sp->fIsStore = FALSE; sp->fIsDebug = TRUE; sp->fIsCall = FALSE; - sp->dwSystemID = TSS_DEBUG_LINE; - fk->cxStoreArray++; + sp->dwSystemID = TSS_DEBUG_LINE; + fk->cxStoreArray++; - return CERR_None; + return CERR_None; } PWCHAR pssBuf = NULL; DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) { - //WCHAR buf[GLOBAL_BUFSIZE]; - int i, j; - DWORD msg; - PWSTR p, q; - char *pp; + //WCHAR buf[GLOBAL_BUFSIZE]; + int i, j; + DWORD msg; + PWSTR p, q; + char *pp; - if(!pssBuf) pssBuf = new WCHAR[GLOBAL_BUFSIZE]; - PWCHAR buf = pssBuf; + if (!pssBuf) pssBuf = new WCHAR[GLOBAL_BUFSIZE]; + PWCHAR buf = pssBuf; - switch(SystemID) - { - case TSS_BITMAP: - if((msg = ImportBitmapFile(fk, sp->dpString, &fk->dwBitmapSize, &fk->lpBitmap)) != CERR_None) - return msg; - break; + switch (SystemID) + { + case TSS_BITMAP: + if ((msg = ImportBitmapFile(fk, sp->dpString, &fk->dwBitmapSize, &fk->lpBitmap)) != CERR_None) + return msg; + break; - case TSS_CALLDEFINITION: - break; + case TSS_CALLDEFINITION: + break; - case TSS_CALLDEFINITION_LOADFAILED: - break; + case TSS_CALLDEFINITION_LOADFAILED: + break; - case TSS_CAPSALWAYSOFF: - if(*sp->dpString == L'1') fk->dwFlags |= KF_CAPSALWAYSOFF; - break; + case TSS_CAPSALWAYSOFF: + if (*sp->dpString == L'1') fk->dwFlags |= KF_CAPSALWAYSOFF; + break; - case TSS_CAPSONONLY: - if(*sp->dpString == L'1') fk->dwFlags |= KF_CAPSONONLY; - break; + case TSS_CAPSONONLY: + if (*sp->dpString == L'1') fk->dwFlags |= KF_CAPSONONLY; + break; - case TSS_COMPILEDVERSION: - break; + case TSS_COMPILEDVERSION: + break; - case TSS_COPYRIGHT: - break; + case TSS_COPYRIGHT: + break; - case TSS_DEBUG_LINE: - break; + case TSS_DEBUG_LINE: + break; - case TSS_ETHNOLOGUECODE: + case TSS_ETHNOLOGUECODE: VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_EthnologueCode); - if((msg = ProcessEthnologueStore(sp->dpString)) != CERR_None) return msg; // I2646 - break; + if ((msg = ProcessEthnologueStore(sp->dpString)) != CERR_None) return msg; // I2646 + break; - case TSS_HOTKEY: - if((msg = ProcessHotKey(sp->dpString, &fk->dwHotKey)) != CERR_None) return msg; + case TSS_HOTKEY: + if ((msg = ProcessHotKey(sp->dpString, &fk->dwHotKey)) != CERR_None) return msg; - swprintf(buf, GLOBAL_BUFSIZE, L"%d", fk->dwHotKey); // I3481 - delete sp->dpString; - sp->dpString = new WCHAR[wcslen(buf)+1]; - wcscpy_s(sp->dpString, wcslen(buf)+1, buf); // I3481 - break; + swprintf(buf, GLOBAL_BUFSIZE, L"%d", (int)fk->dwHotKey); // I3481 + delete[] sp->dpString; + sp->dpString = new WCHAR[wcslen(buf) + 1]; + wcscpy_s(sp->dpString, wcslen(buf) + 1, buf); // I3481 + break; - case TSS_INCLUDECODES: - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); - pp = wstrtostr(sp->dpString); - if(!CodeConstants->LoadFile(pp)) - { - delete pp; - return CERR_CannotLoadIncludeFile; - } - delete pp; - CodeConstants->reindex(); // I4982 - break; - - case TSS_LANGUAGE: + case TSS_INCLUDECODES: + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); + pp = wstrtostr(sp->dpString); + if (!CodeConstants->LoadFile(pp)) { - wchar_t *context = NULL; - q = wcstok_s(sp->dpString, L", ", &context); // I3481 - if(!q) return CERR_InvalidLanguageLine; - - i = xatoi(&q); - q = wcstok_s(NULL, L" c\n", &context); // I3481 - if(!q) - { - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_InvalidLanguageLine); - j = SUBLANGID(i); - i = PRIMARYLANGID(i); - } - else - j = xatoi(&q); - - if(i < 1 || j < 1 || i > 0x3FF || j > 0x3F) return CERR_InvalidLanguageLine; - if(i >= 0x200 || j >= 0x20) AddWarning(CWARN_CustomLanguagesNotSupported); - - fk->KeyboardID = (DWORD) MAKELANGID(i, j); - - swprintf(buf, GLOBAL_BUFSIZE, L"%x %x", i, j); // I3481 - delete sp->dpString; - sp->dpString = new WCHAR[wcslen(buf)+1]; - wcscpy_s(sp->dpString, wcslen(buf)+1, buf); // I3481 - - break; + delete[] pp; + return CERR_CannotLoadIncludeFile; } - case TSS_LANGUAGENAME: - break; + delete[] pp; + CodeConstants->reindex(); // I4982 + break; - case TSS_LAYOUT: - if(fk->KeyboardID == 0) return CERR_LayoutButNoLanguage; + case TSS_LANGUAGE: + { + wchar_t *context = NULL; + q = wcstok_s(sp->dpString, L", ", &context); // I3481 + if (!q) return CERR_InvalidLanguageLine; - q = sp->dpString; + i = xatoi(&q); + q = wcstok_s(NULL, L" c\n", &context); // I3481 + if (!q) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_InvalidLanguageLine); + j = SUBLANGID(i); + i = PRIMARYLANGID(i); + } + else + j = xatoi(&q); - fk->KeyboardID |= (xatoi(&q) << 16L); - break; + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) return CERR_InvalidLanguageLine; + if (i >= 0x200 || j >= 0x20) AddWarning(CWARN_CustomLanguagesNotSupported); - case TSS_MESSAGE: - break; + fk->KeyboardID = (DWORD)MAKELANGID(i, j); - case TSS_MNEMONIC: + swprintf(buf, GLOBAL_BUFSIZE, L"%x %x", i, j); // I3481 + delete[] sp->dpString; + sp->dpString = new WCHAR[wcslen(buf) + 1]; + wcscpy_s(sp->dpString, wcslen(buf) + 1, buf); // I3481 + + break; + } + case TSS_LANGUAGENAME: + break; + + case TSS_LAYOUT: + if (fk->KeyboardID == 0) return CERR_LayoutButNoLanguage; + + q = sp->dpString; + + fk->KeyboardID |= (xatoi(&q) << 16L); + break; + + case TSS_MESSAGE: + break; + + case TSS_MNEMONIC: VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_MnemonicLayout); - FMnemonicLayout = atoiW(sp->dpString) == 1; - break; + FMnemonicLayout = atoiW(sp->dpString) == 1; + break; - case TSS_NAME: - break; + case TSS_NAME: + break; - case TSS_OLDCHARPOSMATCHING: + case TSS_OLDCHARPOSMATCHING: VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_OldCharPosMatching); - FOldCharPosMatching = atoiW(sp->dpString); - break; + FOldCharPosMatching = atoiW(sp->dpString); + break; - case TSS_SHIFTFREESCAPS: - if(*sp->dpString == L'1') fk->dwFlags |= KF_SHIFTFREESCAPS; - break; + case TSS_SHIFTFREESCAPS: + if (*sp->dpString == L'1') fk->dwFlags |= KF_SHIFTFREESCAPS; + break; - case TSS_VERSION: - if((fk->dwFlags & KF_AUTOMATICVERSION) == 0) return CERR_VersionAlreadyIncluded; - p = sp->dpString; + case TSS_VERSION: + if ((fk->dwFlags & KF_AUTOMATICVERSION) == 0) return CERR_VersionAlreadyIncluded; + p = sp->dpString; if (wcstof(p, NULL) < 5.0) { AddWarning(CWARN_OldVersion); } - if(wcsncmp(p, L"3.0", 3) == 0) fk->version = VERSION_50; //0x0a0b000n= a.bn - else if(wcsncmp(p, L"3.1", 3) == 0) fk->version = VERSION_50; //all versions < 5.0 - else if(wcsncmp(p, L"3.2", 3) == 0) fk->version = VERSION_50; //we compile as if - else if(wcsncmp(p, L"4.0", 3) == 0) fk->version = VERSION_50; //they are 5.0.100.0 - else if(wcsncmp(p, L"5.01", 4) == 0) fk->version = VERSION_501; - else if(wcsncmp(p, L"5.0", 3) == 0) fk->version = VERSION_50; - else if(wcsncmp(p, L"6.0", 3) == 0) fk->version = VERSION_60; - else if(wcsncmp(p, L"7.0", 3) == 0) fk->version = VERSION_70; - else if(wcsncmp(p, L"8.0", 3) == 0) fk->version = VERSION_80; - else if(wcsncmp(p, L"9.0", 3) == 0) fk->version = VERSION_90; + if (wcsncmp(p, L"3.0", 3) == 0) fk->version = VERSION_50; //0x0a0b000n= a.bn + else if (wcsncmp(p, L"3.1", 3) == 0) fk->version = VERSION_50; //all versions < 5.0 + else if (wcsncmp(p, L"3.2", 3) == 0) fk->version = VERSION_50; //we compile as if + else if (wcsncmp(p, L"4.0", 3) == 0) fk->version = VERSION_50; //they are 5.0.100.0 + else if (wcsncmp(p, L"5.01", 4) == 0) fk->version = VERSION_501; + else if (wcsncmp(p, L"5.0", 3) == 0) fk->version = VERSION_50; + else if (wcsncmp(p, L"6.0", 3) == 0) fk->version = VERSION_60; + else if (wcsncmp(p, L"7.0", 3) == 0) fk->version = VERSION_70; + else if (wcsncmp(p, L"8.0", 3) == 0) fk->version = VERSION_80; + else if (wcsncmp(p, L"9.0", 3) == 0) fk->version = VERSION_90; else if (wcsncmp(p, L"10.0", 4) == 0) fk->version = VERSION_100; else return CERR_InvalidVersion; - if(fk->version < VERSION_60) FOldCharPosMatching = TRUE; + if (fk->version < VERSION_60) FOldCharPosMatching = TRUE; fk->dwFlags &= ~KF_AUTOMATICVERSION; - break; + break; - case TSS_VISUALKEYBOARD: + case TSS_VISUALKEYBOARD: VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); { // Strip path from the store, leaving bare filename only @@ -1303,11 +1303,12 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) wchar_t *pp = wcsrchr(p, L'\\'); if (!pp) { pp = p; - } else { + } + else { pp++; } q = new WCHAR[wcslen(pp) + 1]; - wcscpy_s(q, wcslen(pp)+1, pp); + wcscpy_s(q, wcslen(pp) + 1, pp); // Change compiled reference file extension to .kvk pp = wcschr(q, 0) - 5; @@ -1315,14 +1316,14 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) pp[4] = 0; } - delete sp->dpString; + delete[] sp->dpString; sp->dpString = q; } break; - case TSS_KMW_RTL: - case TSS_KMW_HELPFILE: - case TSS_KMW_HELPTEXT: - case TSS_KMW_EMBEDJS: + case TSS_KMW_RTL: + case TSS_KMW_HELPFILE: + case TSS_KMW_HELPTEXT: + case TSS_KMW_EMBEDJS: VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); break; @@ -1335,35 +1336,35 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) break; case TSS_WINDOWSLANGUAGES: + { + wchar_t *context = NULL; + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + size_t szQ = wcslen(sp->dpString) * 6 + 1; // I3481 + q = new WCHAR[szQ]; // guaranteed to be enough space for recoding + *q = 0; WCHAR *r = q; + p = wcstok_s(sp->dpString, L" ", &context); // I3481 + while (p) { - wchar_t *context = NULL; - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); - size_t szQ = wcslen(sp->dpString) * 6 + 1; // I3481 - q = new WCHAR[szQ]; // guaranteed to be enough space for recoding - *q = 0; WCHAR *r = q; - p = wcstok_s(sp->dpString, L" ", &context); // I3481 - while(p) - { - int n = xatoi(&p); + int n = xatoi(&p); - j = SUBLANGID(n); - i = PRIMARYLANGID(n); + j = SUBLANGID(n); + i = PRIMARYLANGID(n); - if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) { - delete q; - return CERR_InvalidLanguageLine; - } - - swprintf(r, szQ - (size_t)(r-q), L"x%04.4x ", n); // I3481 - - p = wcstok_s(NULL, L" ", &context); // I3481 - r = wcschr(q, 0); // I3481 + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) { + delete[] q; + return CERR_InvalidLanguageLine; } - delete sp->dpString; - if(*q) *(wcschr(q, 0)-1) = 0; // delete final space - safe because we control the formatting - ugly? scared? - sp->dpString = q; - break; + + swprintf(r, szQ - (size_t)(r - q), L"x%04.4x ", n); // I3481 + + p = wcstok_s(NULL, L" ", &context); // I3481 + r = wcschr(q, 0); // I3481 } + delete[] sp->dpString; + if (*q) *(wcschr(q, 0) - 1) = 0; // delete final space - safe because we control the formatting - ugly? scared? + sp->dpString = q; + break; + } case TSS_COMPARISON: VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); break; @@ -1379,76 +1380,76 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) case TSS_KEYBOARDVERSION: // I4140 VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyKeyboardVersion); - if(!IsValidKeyboardVersion(sp->dpString)) { + if (!IsValidKeyboardVersion(sp->dpString)) { return CERR_KeyboardVersionFormatInvalid; } break; - default: - return CERR_InvalidSystemStore; - } - return CERR_None; + default: + return CERR_InvalidSystemStore; + } + return CERR_None; } BOOL IsValidKeyboardVersion(WCHAR *dpString) { // I4140 /* version format \d+(\.\d+)* e.g. 9.0.3, 1.0, 1.2.3.4, 6.2.1.4.6.4, blank is not allowed */ do { - if(!iswdigit(*dpString)) { + if (!iswdigit(*dpString)) { return FALSE; } - while(iswdigit(*dpString)) { + while (iswdigit(*dpString)) { dpString++; } - if(*dpString == '.') { + if (*dpString == '.') { dpString++; - if(!iswdigit(*dpString)) { + if (!iswdigit(*dpString)) { return FALSE; } } - } while(*dpString != 0); + } while (*dpString != 0); return TRUE; } BOOL GetFileVersion(char *filename, WORD *d1, WORD *d2, WORD *d3, WORD *d4) { - char fnbuf[260]; - DWORD h; - DWORD sz; - PSTR p; - VS_FIXEDFILEINFO *vffi; - UINT len; + char fnbuf[260]; + DWORD h; + DWORD sz; + PSTR p; + VS_FIXEDFILEINFO *vffi; + UINT len; - GetModuleFileName(0, fnbuf, 260); - sz = GetFileVersionInfoSize(fnbuf, &h); - if(sz == 0) return FALSE; - p = new char[sz]; - if(!p) return FALSE; - GetFileVersionInfo(fnbuf, h, sz, p); - VerQueryValue(p, "\\", (void **) &vffi, &len); + GetModuleFileName(0, fnbuf, 260); + sz = GetFileVersionInfoSize(fnbuf, &h); + if (sz == 0) return FALSE; + p = new char[sz]; + if (!p) return FALSE; + GetFileVersionInfo(fnbuf, h, sz, p); + VerQueryValue(p, "\\", (void **)&vffi, &len); - *d1 = HIWORD(vffi->dwFileVersionMS); - *d2 = LOWORD(vffi->dwFileVersionMS); - *d3 = HIWORD(vffi->dwFileVersionLS); - *d4 = LOWORD(vffi->dwFileVersionLS); + *d1 = HIWORD(vffi->dwFileVersionMS); + *d2 = LOWORD(vffi->dwFileVersionMS); + *d3 = HIWORD(vffi->dwFileVersionLS); + *d4 = LOWORD(vffi->dwFileVersionLS); - delete[] p; - return TRUE; + delete[] p; + return TRUE; } DWORD AddCompilerVersionStore(PFILE_KEYBOARD fk) { - WCHAR verstr[32]; - WORD d1, d2, d3, d4; - DWORD msg; + WCHAR verstr[32]; + WORD d1, d2, d3, d4; + DWORD msg; - GetFileVersion(NULL, &d1, &d2, &d3, &d4); - swprintf(verstr, _countof(verstr), L"%d.%d.%d.%d", d1, d2, d3, d4); // I3481 + GetFileVersion(NULL, &d1, &d2, &d3, &d4); + swprintf(verstr, _countof(verstr), L"%d.%d.%d.%d", d1, d2, d3, d4); // I3481 - if((msg = AddStore(fk, TSS_COMPILEDVERSION, verstr)) != CERR_None) return msg; + if ((msg = AddStore(fk, TSS_COMPILEDVERSION, verstr)) != CERR_None) return msg; - return CERR_None; + return CERR_None; } /**************************** @@ -1458,38 +1459,39 @@ DWORD AddCompilerVersionStore(PFILE_KEYBOARD fk) DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PWSTR context, PWSTR output, PWSTR key) { PWSTR p, q; int i; - for(p = output; *p; p=incxstr(p)) { - if(*p == UC_SENTINEL) { - if(*(p+1) == CODE_INDEX) { - int indexStore = *(p+2) - 1; - int contextOffset = *(p+3); - for(q = context, i = 1; *q && i < contextOffset; q=incxstr(q), i++); + for (p = output; *p; p = incxstr(p)) { + if (*p == UC_SENTINEL) { + if (*(p + 1) == CODE_INDEX) { + int indexStore = *(p + 2) - 1; + int contextOffset = *(p + 3); + for (q = context, i = 1; *q && i < contextOffset; q = incxstr(q), i++); - if(*q == 0) { - if(!gp->fUsingKeys) + if (*q == 0) { + if (!gp->fUsingKeys) // no key in the rule, so offset is past end of context return CERR_IndexDoesNotPointToAny; - if(i < contextOffset) // I4914 + if (i < contextOffset) // I4914 // offset is beyond the key return CERR_IndexDoesNotPointToAny; - q = key; - } + q = key; + } - // find the any - if(*q != UC_SENTINEL || *(q+1) != CODE_ANY) + // find the any + if (*q != UC_SENTINEL || *(q + 1) != CODE_ANY) return CERR_IndexDoesNotPointToAny; - int anyStore = *(q+2) - 1; + int anyStore = *(q + 2) - 1; - if(xstrlen(fk->dpStoreArray[indexStore].dpString) < xstrlen(fk->dpStoreArray[anyStore].dpString)) - AddWarning(CWARN_IndexStoreShort); - } else if(*(p+1) == CODE_CONTEXTEX) { - int contextOffset = *(p+2); - if(contextOffset > xstrlen(context)) + if (xstrlen(fk->dpStoreArray[indexStore].dpString) < xstrlen(fk->dpStoreArray[anyStore].dpString)) + AddWarning(CWARN_IndexStoreShort); + } + else if (*(p + 1) == CODE_CONTEXTEX) { + int contextOffset = *(p + 2); + if (contextOffset > xstrlen(context)) return CERR_ContextExHasInvalidOffset; } } - } + } return CERR_None; } @@ -1499,10 +1501,11 @@ DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PWSTR context, PW DWORD CheckUseStatementsInOutput(PWSTR output) { // I4867 BOOL HasUse = FALSE; PWSTR p; - for(p = output; *p; p = incxstr(p)) { - if(*p == UC_SENTINEL && *(p+1) == CODE_USE) { + for (p = output; *p; p = incxstr(p)) { + if (*p == UC_SENTINEL && *(p + 1) == CODE_USE) { HasUse = TRUE; - } else if(HasUse) { + } + else if (HasUse) { AddWarning(CWARN_UseNotLastStatementInRule); return FALSE; } @@ -1512,101 +1515,102 @@ DWORD CheckUseStatementsInOutput(PWSTR output) { // I4867 DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PWSTR str, BOOL IsUnicode) { - PWSTR p, pp; - DWORD msg; - PFILE_GROUP gp; - PFILE_KEY kp; + PWSTR p, pp; + DWORD msg; + PFILE_GROUP gp; + PFILE_KEY kp; PWCHAR pklIn, pklKey, pklOut; - pklIn = new WCHAR[GLOBAL_BUFSIZE]; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer - pklKey = new WCHAR[GLOBAL_BUFSIZE]; - pklOut = new WCHAR[GLOBAL_BUFSIZE]; - if(!pklIn|| !pklKey || !pklOut) + pklIn = new WCHAR[GLOBAL_BUFSIZE]; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer + pklKey = new WCHAR[GLOBAL_BUFSIZE]; + pklOut = new WCHAR[GLOBAL_BUFSIZE]; + if (!pklIn || !pklKey || !pklOut) return CERR_CannotAllocateMemory; // forget about the little leak if pklKey or pklOut fail... __try { - gp = &fk->dpGroupArray[fk->currentGroup]; + gp = &fk->dpGroupArray[fk->currentGroup]; - pp = str; + pp = str; - if(gp->fUsingKeys) { - if((msg = GetXString(fk, str, L"+", pklIn, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(str-pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if (gp->fUsingKeys) { + if ((msg = GetXString(fk, str, L"+", pklIn, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - str = p + 1; - if((msg = GetXString(fk, str, L">", pklKey, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(str-pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - if(pklKey[0] == 0) return CERR_ZeroLengthString; - if(xstrlen(pklKey) > 1) AddWarning(CWARN_KeyBadLength); - } else { - if((msg = GetXString(fk, str, L">", pklIn, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(str-pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - if(pklIn[0] == 0) return CERR_ZeroLengthString; - } + str = p + 1; + if ((msg = GetXString(fk, str, L">", pklKey, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if (pklKey[0] == 0) return CERR_ZeroLengthString; + if (xstrlen(pklKey) > 1) AddWarning(CWARN_KeyBadLength); + } + else { + if ((msg = GetXString(fk, str, L">", pklIn, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if (pklIn[0] == 0) return CERR_ZeroLengthString; + } - str = p + 1; - if((msg = GetXString(fk, str, L"c\n", pklOut, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(str-pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + str = p + 1; + if ((msg = GetXString(fk, str, L"c\n", pklOut, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - if(pklOut[0] == 0) return CERR_ZeroLengthString; + if (pklOut[0] == 0) return CERR_ZeroLengthString; // Test index and context offsets in context - if((msg = CheckStatementOffsets(fk, gp, pklIn, pklOut, pklKey)) != CERR_None) return msg; + if ((msg = CheckStatementOffsets(fk, gp, pklIn, pklOut, pklKey)) != CERR_None) return msg; // Test that use() statements are not followed by other content CheckUseStatementsInOutput(pklOut); // I4867 - kp = new FILE_KEY[gp->cxKeyArray + 1]; - if(!kp) return CERR_CannotAllocateMemory; - if(gp->dpKeyArray) + kp = new FILE_KEY[gp->cxKeyArray + 1]; + if (!kp) return CERR_CannotAllocateMemory; + if (gp->dpKeyArray) + { + memcpy(kp, gp->dpKeyArray, gp->cxKeyArray * sizeof(FILE_KEY)); + delete gp->dpKeyArray; + } + + gp->dpKeyArray = kp; + kp = &gp->dpKeyArray[gp->cxKeyArray]; + gp->cxKeyArray++; + + kp->dpOutput = new WCHAR[wcslen(pklOut) + 1]; + wcscpy_s(kp->dpOutput, wcslen(pklOut) + 1, pklOut); // I3481 + + kp->dpContext = new WCHAR[wcslen(pklIn) + 1]; + wcscpy_s(kp->dpContext, wcslen(pklIn) + 1, pklIn); // I3481 + + kp->Line = currentLine; + + // Finished if we are not using keys + + if (!gp->fUsingKeys) + { + kp->Key = 0; + kp->ShiftFlags = 0; + return CERR_None; + } + + // Expand each rule out into multiple rules - much faster processing at the key hit time + + if (*pklKey == 0) return CERR_ZeroLengthString; + + if (*pklKey == UC_SENTINEL) + switch (*(pklKey + 1)) { - memcpy(kp, gp->dpKeyArray, gp->cxKeyArray * sizeof(FILE_KEY)); - delete gp->dpKeyArray; - } - - gp->dpKeyArray = kp; - kp = &gp->dpKeyArray[gp->cxKeyArray]; - gp->cxKeyArray++; - - kp->dpOutput = new WCHAR[wcslen(pklOut)+1]; - wcscpy_s(kp->dpOutput, wcslen(pklOut)+1, pklOut); // I3481 - - kp->dpContext = new WCHAR[wcslen(pklIn)+1]; - wcscpy_s(kp->dpContext, wcslen(pklIn)+1, pklIn); // I3481 - - kp->Line = currentLine; - - // Finished if we are not using keys - - if(!gp->fUsingKeys) - { - kp->Key = 0; - kp->ShiftFlags = 0; - return CERR_None; - } - - // Expand each rule out into multiple rules - much faster processing at the key hit time - - if(*pklKey == 0) return CERR_ZeroLengthString; - - if(*pklKey == UC_SENTINEL) - switch(*(pklKey+1)) - { - case CODE_ANY: - kp->ShiftFlags = 0; - if((msg = ExpandKp(fk, kp, *(pklKey+2) - 1)) != CERR_None) return msg; - break; + case CODE_ANY: + kp->ShiftFlags = 0; + if ((msg = ExpandKp(fk, kp, *(pklKey + 2) - 1)) != CERR_None) return msg; + break; case CODE_EXTENDED: - kp->Key = *(pklKey+3); - kp->ShiftFlags = *(pklKey+2); - break; + kp->Key = *(pklKey + 3); + kp->ShiftFlags = *(pklKey + 2); + break; default: - return CERR_InvalidCodeInKeyPartOfRule; - } + return CERR_InvalidCodeInKeyPartOfRule; + } else { - kp->ShiftFlags = 0; - kp->Key = *pklKey; + kp->ShiftFlags = 0; + kp->Key = *pklKey; } } @@ -1617,150 +1621,150 @@ DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PWSTR str, BOOL IsUnicode) delete pklOut; } - return CERR_None; + return CERR_None; } DWORD ExpandKp_ReplaceIndex(PFILE_KEYBOARD fk, PFILE_KEY k, DWORD keyIndex, int nAnyIndex) { - /* Replace each index(xx,keyIndex) in k->dpOutput with appropriate char as based on nAnyIndex */ - PFILE_STORE s; - int i; - PWSTR pIndex, pStore; + /* Replace each index(xx,keyIndex) in k->dpOutput with appropriate char as based on nAnyIndex */ + PFILE_STORE s; + int i; + PWSTR pIndex, pStore; - for(pIndex = k->dpOutput; *pIndex; pIndex = incxstr(pIndex)) + for (pIndex = k->dpOutput; *pIndex; pIndex = incxstr(pIndex)) + { + if (*pIndex == UC_SENTINEL && *(pIndex + 1) == CODE_INDEX && *(pIndex + 3) == keyIndex) { - if(*pIndex == UC_SENTINEL && *(pIndex+1) == CODE_INDEX && *(pIndex+3) == keyIndex) - { - s = &fk->dpStoreArray[*(pIndex+2) - 1]; - for(i = 0, pStore = s->dpString; i < nAnyIndex; i++, pStore = incxstr(pStore)); - PWSTR qStore = incxstr(pStore); + s = &fk->dpStoreArray[*(pIndex + 2) - 1]; + for (i = 0, pStore = s->dpString; i < nAnyIndex; i++, pStore = incxstr(pStore)); + PWSTR qStore = incxstr(pStore); - int w = (int)(INT_PTR)(qStore - pStore); - if(w > 4) - { - *pIndex = UC_SENTINEL; - *(pIndex+1) = CODE_BEEP; - memmove(pIndex+2, pIndex+4, wcslen(pIndex+3)*2); - } - else - { - memcpy(pIndex, pStore, w*2); - if(w < 4) memmove(pIndex+w, pIndex+4, wcslen(pIndex+3)*2); - } - } - } + int w = (int)(INT_PTR)(qStore - pStore); + if (w > 4) + { + *pIndex = UC_SENTINEL; + *(pIndex + 1) = CODE_BEEP; + memmove(pIndex + 2, pIndex + 4, wcslen(pIndex + 3) * 2); + } + else + { + memcpy(pIndex, pStore, w * 2); + if (w < 4) memmove(pIndex + w, pIndex + 4, wcslen(pIndex + 3) * 2); + } + } + } - return CERR_None; + return CERR_None; } DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, DWORD storeIndex) { - PFILE_KEY k; - PWSTR pn; - DWORD nchrs, n; - int keyIndex; + PFILE_KEY k; + PWSTR pn; + DWORD nchrs, n; + int keyIndex; - PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; - PFILE_GROUP gp = &fk->dpGroupArray[fk->currentGroup]; + PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; + PFILE_GROUP gp = &fk->dpGroupArray[fk->currentGroup]; - PWSTR dpContext = kpp->dpContext; - PWSTR dpOutput = kpp->dpOutput; + PWSTR dpContext = kpp->dpContext; + PWSTR dpOutput = kpp->dpOutput; - nchrs = xstrlen(sp->dpString); - pn = sp->dpString; - keyIndex = xstrlen(dpContext) + 1; + nchrs = xstrlen(sp->dpString); + pn = sp->dpString; + keyIndex = xstrlen(dpContext) + 1; - /* - Now we change them to plain characters in the output in multiple rules, - and set the keystroke to the appropriate character in the store. - */ + /* + Now we change them to plain characters in the output in multiple rules, + and set the keystroke to the appropriate character in the store. + */ - k = new FILE_KEY[gp->cxKeyArray + nchrs - 1]; - if(!k) return CERR_CannotAllocateMemory; - memcpy(k, gp->dpKeyArray, gp->cxKeyArray * sizeof(FILE_KEY)); + k = new FILE_KEY[gp->cxKeyArray + nchrs - 1]; + if (!k) return CERR_CannotAllocateMemory; + memcpy(k, gp->dpKeyArray, gp->cxKeyArray * sizeof(FILE_KEY)); - kpp = &k[(INT_PTR)(kpp - gp->dpKeyArray)]; + kpp = &k[(INT_PTR)(kpp - gp->dpKeyArray)]; - delete gp->dpKeyArray; - gp->dpKeyArray = k; - gp->cxKeyArray += nchrs - 1; + delete gp->dpKeyArray; + gp->dpKeyArray = k; + gp->cxKeyArray += nchrs - 1; - for(k = kpp, n = 0, pn = sp->dpString; *pn; pn=incxstr(pn), k++, n++) + for (k = kpp, n = 0, pn = sp->dpString; *pn; pn = incxstr(pn), k++, n++) + { + k->dpContext = new WCHAR[wcslen(dpContext) + 1]; + k->dpOutput = new WCHAR[wcslen(dpOutput) + 1]; + + wcscpy_s(k->dpContext, wcslen(dpContext) + 1, dpContext); // copy the context. // I3481 + wcscpy_s(k->dpOutput, wcslen(dpOutput) + 1, dpOutput); // copy the output. + + if (*pn == UC_SENTINEL) { - k->dpContext = new WCHAR[wcslen(dpContext) + 1]; - k->dpOutput = new WCHAR[wcslen(dpOutput) + 1]; + switch (*(pn + 1)) + { + case CODE_EXTENDED: + k->Key = *(pn + 3); // set the key to store offset. + k->ShiftFlags = *(pn + 2); + break; + default: + return CERR_CodeInvalidInKeyStore; + } + } + else + { + k->Key = *pn; // set the key to store offset. + k->ShiftFlags = 0; + } + k->Line = kpp->Line; + ExpandKp_ReplaceIndex(fk, k, keyIndex, n); + } - wcscpy_s(k->dpContext, wcslen(dpContext)+1, dpContext); // copy the context. // I3481 - wcscpy_s(k->dpOutput, wcslen(dpOutput)+1, dpOutput); // copy the output. + delete dpContext; + delete dpOutput; - if(*pn == UC_SENTINEL) - { - switch(*(pn+1)) - { - case CODE_EXTENDED: - k->Key = *(pn+3); // set the key to store offset. - k->ShiftFlags = *(pn+2); - break; - default: - return CERR_CodeInvalidInKeyStore; - } - } - else - { - k->Key = *pn; // set the key to store offset. - k->ShiftFlags = 0; - } - k->Line = kpp->Line; - ExpandKp_ReplaceIndex(fk, k, keyIndex, n); - } - - delete dpContext; - delete dpOutput; - - return CERR_None; + return CERR_None; } PWSTR GetDelimitedString(PWSTR *p, PWSTR Delimiters, WORD Flags) { - PWSTR q, r; - WCHAR dOpen, dClose; + PWSTR q, r; + WCHAR dOpen, dClose; - dOpen = *Delimiters; dClose = *(Delimiters+1); + dOpen = *Delimiters; dClose = *(Delimiters + 1); - q = *p; - while(iswspace(*q)) q++; //***QUERY + q = *p; + while (iswspace(*q)) q++; //***QUERY - if(*q != dOpen) return NULL; + if (*q != dOpen) return NULL; - q++; + q++; - r = wcschr(q, dClose); // Find closing delimiter - if(!r) return NULL; + r = wcschr(q, dClose); // Find closing delimiter + if (!r) return NULL; - if(Flags & GDS_CUTLEAD) - while(iswspace(*q)) q++; // cut off leading spaces + if (Flags & GDS_CUTLEAD) + while (iswspace(*q)) q++; // cut off leading spaces - if(Flags & GDS_CUTFOLL) - if(!iswspace(*(r-1))) *r = 0; - else - { - r--; // Cut off following spaces - while(iswspace(*r) && r > q) r--; - r++; - *r = 0; r = wcschr((r + 1), dClose); - } - else *r = 0; + if (Flags & GDS_CUTFOLL) + if (!iswspace(*(r - 1))) *r = 0; + else + { + r--; // Cut off following spaces + while (iswspace(*r) && r > q) r--; + r++; + *r = 0; r = wcschr((r + 1), dClose); + } + else *r = 0; - r++; while(iswspace(*r)) r++; // Ignore spaces after the close - if(*r == 0) r--; // Safety for terminating strings. + r++; while (iswspace(*r)) r++; // Ignore spaces after the close + if (*r == 0) r--; // Safety for terminating strings. - *p = r; // Update pointer position + *p = r; // Update pointer position - return q; // Return delimited string + return q; // Return delimited string } @@ -1768,30 +1772,30 @@ enum LinePrefixType { lptNone, lptKeymanAndKeymanWeb, lptKeymanWebOnly, lptKeyma LinePrefixType GetLinePrefixType(PWSTR *p) { - PWSTR s = *p; + PWSTR s = *p; - while(iswspace(*s)) s++; + while (iswspace(*s)) s++; PWSTR q = s; - if(*s != '$') return lptNone; + if (*s != '$') return lptNone; /* I1569 - fix named constants at the start of the line */ s++; - while(__iswcsym(*s)) s++; - if(*s != ':') return lptNone; + while (__iswcsym(*s)) s++; + if (*s != ':') return lptNone; - if(_wcsnicmp(q, L"$keyman:", 8) == 0) + if (_wcsnicmp(q, L"$keyman:", 8) == 0) { - *p += 8; + *p += 8; return lptKeymanAndKeymanWeb; - } - if(_wcsnicmp(q, L"$keymanweb:", 11) == 0) + } + if (_wcsnicmp(q, L"$keymanweb:", 11) == 0) { *p += 11; return lptKeymanWebOnly; } - if(_wcsnicmp(q, L"$keymanonly:", 12) == 0) + if (_wcsnicmp(q, L"$keymanonly:", 12) == 0) { *p += 12; return lptKeymanOnly; @@ -1804,64 +1808,64 @@ int LineTokenType(PWSTR *str) { int i; size_t l; - PWSTR p = *str; + PWSTR p = *str; LinePrefixType lpt = GetLinePrefixType(&p); - if(lpt == lptOther) return T_BLANK; + if (lpt == lptOther) return T_BLANK; /* Test KeymanWeb, Keyman and KeymanOnly prefixes */ - if(CompileTarget == CKF_KEYMAN && lpt == lptKeymanWebOnly) return T_BLANK; - if(CompileTarget == CKF_KEYMANWEB && lpt == lptKeymanOnly) return T_BLANK; + if (CompileTarget == CKF_KEYMAN && lpt == lptKeymanWebOnly) return T_BLANK; + if (CompileTarget == CKF_KEYMANWEB && lpt == lptKeymanOnly) return T_BLANK; - while(iswspace(*p)) p++; + while (iswspace(*p)) p++; - if(wcschr(LineTokens[0], towupper(*p))) - for(i = 0; i <= T_W_END - T_W_START; i++) - { - l = wcslen(LineTokens[i+1]); - if(_wcsnicmp(p, LineTokens[i+1], l) == 0) - { - p += l; while(iswspace(*p)) p++; *str = p; - return i + T_W_START; - } - } - - switch(towupper(*p)) + if (wcschr(LineTokens[0], towupper(*p))) + for (i = 0; i <= T_W_END - T_W_START; i++) { - case 'C': - if(iswspace(*(p+1))) return T_COMMENT; - break; - case 0: - return T_BLANK; - default: - if(wcschr(L"\"aAbBlLpPnN[OoxXdD0123456789\'+UuiI$", *p)) // I4784 - { - *str = p; - return T_KEYTOKEY; - } - } - return T_UNKNOWN; + l = wcslen(LineTokens[i + 1]); + if (_wcsnicmp(p, LineTokens[i + 1], l) == 0) + { + p += l; while (iswspace(*p)) p++; *str = p; + return i + T_W_START; + } + } + + switch (towupper(*p)) + { + case 'C': + if (iswspace(*(p + 1))) return T_COMMENT; + break; + case 0: + return T_BLANK; + default: + if (wcschr(L"\"aAbBlLpPnN[OoxXdD0123456789\'+UuiI$", *p)) // I4784 + { + *str = p; + return T_KEYTOKEY; + } + } + return T_UNKNOWN; } const PWSTR DeadKeyChars = - L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; +L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; BOOL strvalidchrs(PWSTR q, PWSTR chrs) { - for(; *q; q++) - if(!wcschr(chrs, *q)) return FALSE; - return TRUE; + for (; *q; q++) + if (!wcschr(chrs, *q)) return FALSE; + return TRUE; } DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int max, int offset, PWSTR *newp, int isVKey, int isUnicode) { - DWORD err; - PWSTR p = str, q, r; - int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, sFlag = 0, j; - DWORD i; - BOOL finished = FALSE; - WCHAR c; - PSTR codename; + DWORD err; + PWSTR p = str, q, r; + int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, sFlag = 0, j; + DWORD i; + BOOL finished = FALSE; + WCHAR c; + PSTR codename; PWCHAR tstr = NULL; int tstrMax = 0; @@ -1873,406 +1877,406 @@ DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int ma { *tstr = 0; - *output = 0; + *output = 0; - p = str; - do + p = str; + do + { + tokenFound = FALSE; + while (iswspace(*p) && !wcschr(token, *p)) p++; + if (!*p) break; + + ErrChr = (int)(INT_PTR)(p - str) + offset + 1; + + /* + char *tokenTypes[] = { + "clearcontext", "deadkey", "context", "return", "switch", + "index", "outs", "beep", "nul", "use", "any", "fix", "dk", "k_", "x", "d", "c", + "[", "]" }; + */ + + switch (towupper(*p)) { - tokenFound = FALSE; - while(iswspace(*p) && !wcschr(token, *p)) p++; - if(!*p) break; - - ErrChr = (int)(INT_PTR)(p - str) + offset + 1; - - /* - char *tokenTypes[] = { - "clearcontext", "deadkey", "context", "return", "switch", - "index", "outs", "beep", "nul", "use", "any", "fix", "dk", "k_", "x", "d", "c", - "[", "]" }; - */ - - switch(towupper(*p)) - { - case 'X': - case 'D': type = 0; break; // xFF, d130: chars, deadkey(n) - case '\"': type = 1; break; // "xxxx": chars - case '\'': type = 2; break; // 'xxxx': chars - case 'A': type = 3; break; // any(s) - case 'B': type = 4; break; // beep, baselayout (synonym for if(&baselayout)) // I3430 - case 'I': type = 5; break; // index(s,n), if - case 'O': type = 6; break; // outs(s) - case 'C': type = 7; break; // context, comments, clearcontext, call(s) - case 'N': type = 8; break; // nul, notany - case 'U': type = 9; break; // use(g) - case 'R': type = 10; break; // return, reset - case '[': type = 11; break; // start of vkey section - //case ']': type = 12; break; // end of vkey section - //case 'K': type = 13; break; // virtual key name or "key" - case 'S': type = 14; break; // switch, set, save - case 'F': type = 15; break; // fix (synonym for clearcontext) - case '$': type = 16; break; // named code constants - case 'P': type = 17; break; // platform (synonym for if(&platform)) // I3430 - case 'L': type = 18; break; // layer (synonym for set(&layer)) // I3437 - default: - if(iswdigit(*p)) type = 0; // octal number - else type = 99; // error! + case 'X': + case 'D': type = 0; break; // xFF, d130: chars, deadkey(n) + case '\"': type = 1; break; // "xxxx": chars + case '\'': type = 2; break; // 'xxxx': chars + case 'A': type = 3; break; // any(s) + case 'B': type = 4; break; // beep, baselayout (synonym for if(&baselayout)) // I3430 + case 'I': type = 5; break; // index(s,n), if + case 'O': type = 6; break; // outs(s) + case 'C': type = 7; break; // context, comments, clearcontext, call(s) + case 'N': type = 8; break; // nul, notany + case 'U': type = 9; break; // use(g) + case 'R': type = 10; break; // return, reset + case '[': type = 11; break; // start of vkey section + //case ']': type = 12; break; // end of vkey section + //case 'K': type = 13; break; // virtual key name or "key" + case 'S': type = 14; break; // switch, set, save + case 'F': type = 15; break; // fix (synonym for clearcontext) + case '$': type = 16; break; // named code constants + case 'P': type = 17; break; // platform (synonym for if(&platform)) // I3430 + case 'L': type = 18; break; // layer (synonym for set(&layer)) // I3437 + default: + if (iswdigit(*p)) type = 0; // octal number + else type = 99; // error! } - if(wcschr(token, *p)) tokenFound = TRUE; + if (wcschr(token, *p)) tokenFound = TRUE; - switch(type) - { - case 99: - if(tokenFound) break; - wsprintf(ErrExtra, "token: %c", (int) *p); - return CERR_InvalidToken; - case 0: - if(_wcsnicmp(p, L"deadkey", z = 7) == 0 || - _wcsnicmp(p, L"dk", z = 2) == 0 ) + switch (type) + { + case 99: + if (tokenFound) break; + wsprintf(ErrExtra, "token: %c", (int)*p); + return CERR_InvalidToken; + case 0: + if (_wcsnicmp(p, L"deadkey", z = 7) == 0 || + _wcsnicmp(p, L"dk", z = 2) == 0) { - p += z; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidDeadkey; + p += z; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidDeadkey; - DWORD n = fk->cxDeadKeyArray; + DWORD n = fk->cxDeadKeyArray; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_DEADKEY; - if(!strvalidchrs(q, DeadKeyChars)) return CERR_InvalidDeadkey; - tstr[mx++] = GetDeadKey(fk, q); //atoiW(q); 7-5-01: named deadkeys - tstr[mx] = 0; - } - else + tstr[mx++] = CODE_DEADKEY; + if (!strvalidchrs(q, DeadKeyChars)) return CERR_InvalidDeadkey; + tstr[mx++] = GetDeadKey(fk, q); //atoiW(q); 7-5-01: named deadkeys + tstr[mx] = 0; + } + else { - n = xatoi(&p); - if(*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; - if((err = UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; - tstr[mx++] = n1; - if(n2 >= 0) tstr[mx++] = n2; - tstr[mx] = 0; - } - continue; - case 1: - q = wcschr(p+1, '\"'); - if(!q) return CERR_UnterminatedString; - if((INT_PTR)(q-p) - 1 + mx > max) return CERR_UnterminatedString; - if(sFlag) return CERR_StringInVirtualKeySection; - wcsncat_s(tstr, max, p+1, (INT_PTR)(q-p)-1); // I3481 - mx += (int)(INT_PTR)(q-p)-1; - tstr[mx] = 0; - p = q+1; - continue; - case 2: - q = wcschr(p+1, '\''); - if(!q) return CERR_UnterminatedString; - if((INT_PTR)(q-p) - 1 + mx > max) return CERR_UnterminatedString; - if(sFlag) return CERR_StringInVirtualKeySection; - wcsncat_s(tstr, max, p+1, (INT_PTR)(q-p)-1); // I3481 - mx += (int)(INT_PTR)(q-p)-1; - tstr[mx] = 0; - p = q+1; - continue; - case 3: - if(_wcsnicmp(p, L"any", 3) != 0) return CERR_InvalidToken; - if(sFlag) return CERR_AnyInVirtualKeySection; - p += 3; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidAny; + n = xatoi(&p); + if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; + if ((err = UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; + tstr[mx++] = n1; + if (n2 >= 0) tstr[mx++] = n2; + tstr[mx] = 0; + } + continue; + case 1: + q = wcschr(p + 1, '\"'); + if (!q) return CERR_UnterminatedString; + if ((INT_PTR)(q - p) - 1 + mx > max) return CERR_UnterminatedString; + if (sFlag) return CERR_StringInVirtualKeySection; + wcsncat_s(tstr, max, p + 1, (INT_PTR)(q - p) - 1); // I3481 + mx += (int)(INT_PTR)(q - p) - 1; + tstr[mx] = 0; + p = q + 1; + continue; + case 2: + q = wcschr(p + 1, '\''); + if (!q) return CERR_UnterminatedString; + if ((INT_PTR)(q - p) - 1 + mx > max) return CERR_UnterminatedString; + if (sFlag) return CERR_StringInVirtualKeySection; + wcsncat_s(tstr, max, p + 1, (INT_PTR)(q - p) - 1); // I3481 + mx += (int)(INT_PTR)(q - p) - 1; + tstr[mx] = 0; + p = q + 1; + continue; + case 3: + if (_wcsnicmp(p, L"any", 3) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_AnyInVirtualKeySection; + p += 3; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidAny; - for(i = 0; i < fk->cxStoreArray; i++) - { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + for (i = 0; i < fk->cxStoreArray; i++) + { + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; - if(!*fk->dpStoreArray[i].dpString) return CERR_ZeroLengthString; + if (!*fk->dpStoreArray[i].dpString) return CERR_ZeroLengthString; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_ANY; - tstr[mx++] = (WCHAR)i+1; // store to index + 1, avoids End-of-string - tstr[mx] = 0; - continue; - case 4: - if(_wcsnicmp(p, L"beep", 4) == 0) + tstr[mx++] = CODE_ANY; + tstr[mx++] = (WCHAR)i + 1; // store to index + 1, avoids End-of-string + tstr[mx] = 0; + continue; + case 4: + if (_wcsnicmp(p, L"beep", 4) == 0) { - if(sFlag) return CERR_BeepInVirtualKeySection; - p += 4; + if (sFlag) return CERR_BeepInVirtualKeySection; + p += 4; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_BEEP; - tstr[mx] = 0; + tstr[mx++] = CODE_BEEP; + tstr[mx] = 0; } - else if(_wcsnicmp(p, L"baselayout", 10) == 0) // I3430 + else if (_wcsnicmp(p, L"baselayout", 10) == 0) // I3430 { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); - if(sFlag) return CERR_InvalidInVirtualKeySection; - p += 10; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 10; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return CERR_InvalidToken; err = process_baselayout(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else return CERR_InvalidToken; - continue; - case 5: - if(_wcsnicmp( p, L"if", 2) == 0) + continue; + case 5: + if (_wcsnicmp(p, L"if", 2) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); - if(sFlag) return CERR_InvalidInVirtualKeySection; + if (sFlag) return CERR_InvalidInVirtualKeySection; p += 2; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidIf; + if (!q || !*q) return CERR_InvalidIf; err = process_if(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else { - if(_wcsnicmp( p, L"index", 5) != 0) return CERR_InvalidToken; - if(sFlag) return CERR_IndexInVirtualKeySection; - p += 5; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (_wcsnicmp(p, L"index", 5) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_IndexInVirtualKeySection; + p += 5; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidIndex; + if (!q || !*q) return CERR_InvalidIndex; { wchar_t *context = NULL; - r = wcstok_s(q, L" ,", &context); // I3481 - if(!r) return CERR_InvalidIndex; + r = wcstok_s(q, L" ,", &context); // I3481 + if (!r) return CERR_InvalidIndex; - for(i=0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); r = wcstok_s(NULL, L" ,", &context); // I3481 - if(!r) return CERR_InvalidIndex; + if (!r) return CERR_InvalidIndex; } tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_INDEX; - tstr[mx++] = (WCHAR)i+1; // avoid EOS for stores - tstr[mx++] = atoiW(r); // character offset of original any. + tstr[mx++] = CODE_INDEX; + tstr[mx++] = (WCHAR)i + 1; // avoid EOS for stores + tstr[mx++] = atoiW(r); // character offset of original any. - tstr[mx] = 0; + tstr[mx] = 0; } - continue; - case 6: - if(_wcsnicmp(p, L"outs", 4) != 0) return CERR_InvalidToken; - if(sFlag) return CERR_OutsInVirtualKeySection; - p += 4; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidOuts; + continue; + case 6: + if (_wcsnicmp(p, L"outs", 4) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_OutsInVirtualKeySection; + p += 4; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidOuts; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); - for(q = fk->dpStoreArray[i].dpString; *q; q++) + for (q = fk->dpStoreArray[i].dpString; *q; q++) { - tstr[mx++] = *q; - if(mx >= max-1) return CERR_BufferOverflow; - } - tstr[mx] = 0; - continue; - case 7: - if(iswspace(*(p+1))) break; // is a comment -- pre-stripped - so why this test? - if(_wcsnicmp(p, L"context", 7) == 0) + tstr[mx++] = *q; + if (mx >= max - 1) return CERR_BufferOverflow; + } + tstr[mx] = 0; + continue; + case 7: + if (iswspace(*(p + 1))) break; // is a comment -- pre-stripped - so why this test? + if (_wcsnicmp(p, L"context", 7) == 0) { - if(sFlag) return CERR_ContextInVirtualKeySection; - p += 7; + if (sFlag) return CERR_ContextInVirtualKeySection; + p += 7; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(q && *q) - { + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (q && *q) + { VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_Contextn); - int n1; - n1 = atoiW(q); - if(n1 < 1 || n1 >= 0xF000) return CERR_InvalidToken; - tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CONTEXTEX; - tstr[mx++] = n1; - tstr[mx] = 0; - } - else - { - tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CONTEXT; - tstr[mx] = 0; - } - } - else if(_wcsnicmp(p, L"clearcontext", 12) == 0) + int n1; + n1 = atoiW(q); + if (n1 < 1 || n1 >= 0xF000) return CERR_InvalidToken; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CONTEXTEX; + tstr[mx++] = n1; + tstr[mx] = 0; + } + else + { + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CONTEXT; + tstr[mx] = 0; + } + } + else if (_wcsnicmp(p, L"clearcontext", 12) == 0) + { + p += 12; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CLEARCONTEXT; + tstr[mx] = 0; + } + else if (_wcsnicmp(p, L"call", 4) == 0) { - p += 12; - tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CLEARCONTEXT; - tstr[mx] = 0; - } - else if(_wcsnicmp(p, L"call", 4) == 0) - { VERIFY_KEYBOARD_VERSION(fk, VERSION_501, CERR_501FeatureOnly_Call); - if(sFlag) return CERR_CallInVirtualKeySection; - p += 4; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidCall; + if (sFlag) return CERR_CallInVirtualKeySection; + p += 4; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidCall; - for(i = 0; i < fk->cxStoreArray; i++) - { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } + for (i = 0; i < fk->cxStoreArray; i++) + { + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } - if(!IsValidCallStore(&fk->dpStoreArray[i])) return CERR_InvalidCall; + if (!IsValidCallStore(&fk->dpStoreArray[i])) return CERR_InvalidCall; CheckStoreUsage(fk, i, FALSE, FALSE, TRUE); - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; - tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CALL; - tstr[mx++] = (WCHAR)i+1; - tstr[mx] = 0; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CALL; + tstr[mx++] = (WCHAR)i + 1; + tstr[mx] = 0; - fk->dpStoreArray[i].dwSystemID = TSS_CALLDEFINITION; - } - else - return CERR_InvalidToken; - continue; - case 8: - if(_wcsnicmp(p, L"notany", 6) == 0) - { + fk->dpStoreArray[i].dwSystemID = TSS_CALLDEFINITION; + } + else + return CERR_InvalidToken; + continue; + case 8: + if (_wcsnicmp(p, L"notany", 6) == 0) + { VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly) - if(sFlag) return CERR_AnyInVirtualKeySection; - p += 6; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidAny; + if (sFlag) return CERR_AnyInVirtualKeySection; + p += 6; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidAny; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_NOTANY; - tstr[mx++] = (WCHAR)i+1; // store to index + 1, avoids End-of-string - tstr[mx] = 0; - continue; - } - if(_wcsnicmp(p, L"nul", 3) != 0) return CERR_InvalidToken; + tstr[mx++] = CODE_NOTANY; + tstr[mx++] = (WCHAR)i + 1; // store to index + 1, avoids End-of-string + tstr[mx] = 0; + continue; + } + if (_wcsnicmp(p, L"nul", 3) != 0) return CERR_InvalidToken; - p += 3; + p += 3; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_NUL; - tstr[mx] = 0; - continue; - case 9: - if(_wcsnicmp(p, L"use", 3) != 0) + tstr[mx++] = CODE_NUL; + tstr[mx] = 0; + continue; + case 9: + if (_wcsnicmp(p, L"use", 3) != 0) { - if(*(p+1) == '+') + if (*(p + 1) == '+') { - n = xatoi(&p); - if(*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; - if((err = UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; - tstr[mx++] = n1; - if(n2 >= 0) tstr[mx++] = n2; - tstr[mx] = 0; - if(!isUnicode) AddWarning(CWARN_UnicodeInANSIGroup); + n = xatoi(&p); + if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; + if ((err = UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; + tstr[mx++] = n1; + if (n2 >= 0) tstr[mx++] = n2; + tstr[mx] = 0; + if (!isUnicode) AddWarning(CWARN_UnicodeInANSIGroup); continue; } return CERR_InvalidToken; } - p += 3; + p += 3; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidUse; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidUse; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_USE; - tstr[mx] = GetGroupNum(fk, q); - if( tstr[mx] == 0 ) return CERR_GroupDoesNotExist; - tstr[++mx] = 0; - continue; - case 10: - if(_wcsnicmp(p, L"reset", 5) == 0) + tstr[mx++] = CODE_USE; + tstr[mx] = GetGroupNum(fk, q); + if (tstr[mx] == 0) return CERR_GroupDoesNotExist; + tstr[++mx] = 0; + continue; + case 10: + if (_wcsnicmp(p, L"reset", 5) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); - if(sFlag) return CERR_InvalidInVirtualKeySection; + if (sFlag) return CERR_InvalidInVirtualKeySection; p += 5; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidReset; + if (!q || !*q) return CERR_InvalidReset; err = process_reset(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else { - if(_wcsnicmp(p, L"return", 6) != 0) return CERR_InvalidToken; + if (_wcsnicmp(p, L"return", 6) != 0) return CERR_InvalidToken; - p += 6; + p += 6; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_RETURN; - tstr[mx] = 0; - wcsncpy_s(output, max, tstr, max); // I3481 - output[max-1] = 0; - return 0; + tstr[mx] = 0; + wcsncpy_s(output, max, tstr, max); // I3481 + output[max - 1] = 0; + return 0; } continue; - case 11: - p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; + case 11: + p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; - //printf("--EXTENDEDSTRING--\n"); + //printf("--EXTENDEDSTRING--\n"); - do + do { - while(iswspace(*p)) p++; + while (iswspace(*p)) p++; - switch(towupper(*p)) - { - case 'N': - if(_wcsnicmp(p, L"NCAPS", 5) == 0) - sFlag |= NOTCAPITALFLAG, p += 5; - else finished = TRUE; - break; - case 'L': - if(_wcsnicmp(p, L"LALT", 4) == 0) - sFlag |= LALTFLAG, p += 4; - else if(_wcsnicmp(p, L"LCTRL", 5) == 0) - sFlag |= LCTRLFLAG, p += 5; - else finished = TRUE; - break; - case 'R': - if(_wcsnicmp(p, L"RALT", 4) == 0) - sFlag |= RALTFLAG, p += 4; - else if(_wcsnicmp(p, L"RCTRL", 5) == 0) - sFlag |= RCTRLFLAG, p += 5; - else finished = TRUE; - break; - case 'A': - if(_wcsnicmp(p, L"ALT", 3) == 0) - sFlag |= K_ALTFLAG, p += 3; - else finished = TRUE; - break; - case 'C': - if(_wcsnicmp(p, L"CTRL", 4) == 0) - sFlag |= K_CTRLFLAG, p += 4; - else if(_wcsnicmp(p, L"CAPS", 4) == 0) - sFlag |= CAPITALFLAG, p += 4; - else finished = TRUE; - break; - case 'S': - if(_wcsnicmp(p, L"SHIFT", 5) == 0) - sFlag |= K_SHIFTFLAG, p += 5; - else finished = TRUE; - break; - default: - finished = TRUE; - break; - } - } while(!finished); + switch (towupper(*p)) + { + case 'N': + if (_wcsnicmp(p, L"NCAPS", 5) == 0) + sFlag |= NOTCAPITALFLAG, p += 5; + else finished = TRUE; + break; + case 'L': + if (_wcsnicmp(p, L"LALT", 4) == 0) + sFlag |= LALTFLAG, p += 4; + else if (_wcsnicmp(p, L"LCTRL", 5) == 0) + sFlag |= LCTRLFLAG, p += 5; + else finished = TRUE; + break; + case 'R': + if (_wcsnicmp(p, L"RALT", 4) == 0) + sFlag |= RALTFLAG, p += 4; + else if (_wcsnicmp(p, L"RCTRL", 5) == 0) + sFlag |= RCTRLFLAG, p += 5; + else finished = TRUE; + break; + case 'A': + if (_wcsnicmp(p, L"ALT", 3) == 0) + sFlag |= K_ALTFLAG, p += 3; + else finished = TRUE; + break; + case 'C': + if (_wcsnicmp(p, L"CTRL", 4) == 0) + sFlag |= K_CTRLFLAG, p += 4; + else if (_wcsnicmp(p, L"CAPS", 4) == 0) + sFlag |= CAPITALFLAG, p += 4; + else finished = TRUE; + break; + case 'S': + if (_wcsnicmp(p, L"SHIFT", 5) == 0) + sFlag |= K_SHIFTFLAG, p += 5; + else finished = TRUE; + break; + default: + finished = TRUE; + break; + } + } while (!finished); if ((sFlag & (LCTRLFLAG | LALTFLAG)) && (sFlag & (RCTRLFLAG | RALTFLAG))) { AddWarning(CWARN_MixingLeftAndRightModifiers); @@ -2283,70 +2287,70 @@ DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int ma // in the web target platform, even if there are platform() rules excluding this possibility. In that (rare) situation, the keyboard developer should simply specify // the &version to be 9.0 or whatever to avoid this behaviour. if (sFlag & (LCTRLFLAG | LALTFLAG | RCTRLFLAG | RALTFLAG | CAPITALFLAG | NOTCAPITALFLAG | NUMLOCKFLAG | NOTNUMLOCKFLAG | SCROLLFLAG | NOTSCROLLFLAG) && - CompileTarget == CKF_KEYMANWEB && - fk->dwFlags & KF_AUTOMATICVERSION) { + CompileTarget == CKF_KEYMANWEB && + fk->dwFlags & KF_AUTOMATICVERSION) { VERIFY_KEYBOARD_VERSION(fk, VERSION_100, 0); } - //printf("sFlag: %x\n", sFlag); + //printf("sFlag: %x\n", sFlag); tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_EXTENDED; - tstr[mx++] = sFlag; + tstr[mx++] = CODE_EXTENDED; + tstr[mx++] = sFlag; - while(iswspace(*p)) p++; + while (iswspace(*p)) p++; - q = p; + q = p; - if(*q == ']') + if (*q == ']') { return CERR_InvalidToken; // I3137 - key portion of VK is missing e.g. "[CTRL ALT]", this generates invalid kmx file that can crash Keyman or compiler later on // I3511 } - while(*q != ']') - { - if(*q == '\'' || *q == '"') - { + while (*q != ']') + { + if (*q == '\'' || *q == '"') + { VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_VirtualCharKey); - if(!FMnemonicLayout) AddWarning(CWARN_VirtualCharKeyWithPositionalLayout); - WCHAR chQuote = *q; - q++; if(*q == chQuote || *q == '\n' || *q == 0) return CERR_InvalidToken; - tstr[mx-1] |= VIRTUALCHARKEY; - tstr[mx++] = *q; - q++; if(*q != chQuote) return CERR_InvalidToken; - q++; - while(iswspace(*q)) q++; - if(*q != ']') return CERR_InvalidToken; - break; /* out of while loop */ - } + if (!FMnemonicLayout) AddWarning(CWARN_VirtualCharKeyWithPositionalLayout); + WCHAR chQuote = *q; + q++; if (*q == chQuote || *q == '\n' || *q == 0) return CERR_InvalidToken; + tstr[mx - 1] |= VIRTUALCHARKEY; + tstr[mx++] = *q; + q++; if (*q != chQuote) return CERR_InvalidToken; + q++; + while (iswspace(*q)) q++; + if (*q != ']') return CERR_InvalidToken; + break; /* out of while loop */ + } - for(j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); + for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); - if(*q == 0) return CERR_InvalidToken; + if (*q == 0) return CERR_InvalidToken; WCHAR vkname[SZMAX_VKDICTIONARYNAME]; // I3438 - if(j >= SZMAX_VKDICTIONARYNAME) return CERR_InvalidToken; + if (j >= SZMAX_VKDICTIONARYNAME) return CERR_InvalidToken; wcsncpy_s(vkname, _countof(vkname), p, j); // I3481 vkname[j] = 0; - if(_wcsicmp(vkname, L"K_NPENTER") == 0) - i = 5; // I649 - K_NPENTER hack - else + if (_wcsicmp(vkname, L"K_NPENTER") == 0) + i = 5; // I649 - K_NPENTER hack + else { - for(i = 0; i <= VK__MAX; i++) - { - if(_wcsicmp(vkname, VKeyNames[i]) == 0 || _wcsicmp(vkname, VKeyISO9995Names[i]) == 0) - break; - } + for (i = 0; i <= VK__MAX; i++) + { + if (_wcsicmp(vkname, VKeyNames[i]) == 0 || _wcsicmp(vkname, VKeyISO9995Names[i]) == 0) + break; + } } - if(i == VK__MAX + 1) + if (i == VK__MAX + 1) { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_InvalidToken); i = GetVKCode(fk, vkname); // I3438 - if(i == 0) + if (i == 0) return CERR_InvalidToken; } @@ -2354,134 +2358,134 @@ DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int ma tstr[mx++] = (int)i; - if(FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) AddWarning(CWARN_VirtualKeyWithMnemonicLayout); // I3438 + if (FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) AddWarning(CWARN_VirtualKeyWithMnemonicLayout); // I3438 - while(iswspace(*q)) q++; - } - tstr[mx++] = UC_SENTINEL_EXTENDEDEND; - tstr[mx] = 0; - //printf("--EXTENDEDEND--\n"); + while (iswspace(*q)) q++; + } + tstr[mx++] = UC_SENTINEL_EXTENDEDEND; + tstr[mx] = 0; + //printf("--EXTENDEDEND--\n"); - p = q+1; + p = q + 1; - sFlag = 0; + sFlag = 0; - continue; - case 14: - if(_wcsnicmp(p, L"set", 3) == 0) + continue; + case 14: + if (_wcsnicmp(p, L"set", 3) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); p += 3; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidSet; + if (!q || !*q) return CERR_InvalidSet; err = process_set(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } - else if(_wcsnicmp(p, L"save", 4) == 0) + else if (_wcsnicmp(p, L"save", 4) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); p += 4; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidSave; + if (!q || !*q) return CERR_InvalidSave; err = process_save(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else { - if(_wcsnicmp(p, L"switch", 6) != 0) return CERR_InvalidToken; - p += 6; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidSwitch; + if (_wcsnicmp(p, L"switch", 6) != 0) return CERR_InvalidToken; + p += 6; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidSwitch; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_SWITCH; - tstr[mx++] = atoiW(q); - tstr[mx] = 0; + tstr[mx++] = CODE_SWITCH; + tstr[mx++] = atoiW(q); + tstr[mx] = 0; } - continue; - case 15: - if(_wcsnicmp(p, L"fix", 3) == 0) + continue; + case 15: + if (_wcsnicmp(p, L"fix", 3) == 0) { - p += 3; + p += 3; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CLEARCONTEXT; - tstr[mx] = 0; - } - else - return CERR_InvalidToken; - continue; - case 16: + tstr[mx++] = CODE_CLEARCONTEXT; + tstr[mx] = 0; + } + else + return CERR_InvalidToken; + continue; + case 16: VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); - q = p+1; - while(iswalnum(*q) || *q == '-' || *q == '_') q++; - c = *q; *q = 0; - codename = wstrtostr(p+1); - *q = c; - n = CodeConstants->GetCode(codename, &i); - delete codename; - if(n == 0) return CERR_InvalidNamedCode; - if(i < 0xFFFFFFFFL) CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); // I2993 - if(n > 0xFFFF) - { - tstr[mx++] = Uni_UTF32ToSurrogate1(n); - tstr[mx++] = Uni_UTF32ToSurrogate2(n); - } - else - tstr[mx++] = n; - tstr[mx] = 0; - p = q; - continue; + q = p + 1; + while (iswalnum(*q) || *q == '-' || *q == '_') q++; + c = *q; *q = 0; + codename = wstrtostr(p + 1); + *q = c; + n = CodeConstants->GetCode(codename, &i); + delete[] codename; + if (n == 0) return CERR_InvalidNamedCode; + if (i < 0xFFFFFFFFL) CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); // I2993 + if (n > 0xFFFF) + { + tstr[mx++] = Uni_UTF32ToSurrogate1(n); + tstr[mx++] = Uni_UTF32ToSurrogate2(n); + } + else + tstr[mx++] = n; + tstr[mx] = 0; + p = q; + continue; case 17: - if(_wcsnicmp(p, L"platform", 8) != 0) return CERR_InvalidToken; // I3430 + if (_wcsnicmp(p, L"platform", 8) != 0) return CERR_InvalidToken; // I3430 VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); - if(sFlag) return CERR_InvalidInVirtualKeySection; - p += 8; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 8; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return CERR_InvalidToken; err = process_platform(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; continue; case 18: // I3437 - if(_wcsnicmp(p, L"layer", 5) != 0) return CERR_InvalidToken; + if (_wcsnicmp(p, L"layer", 5) != 0) return CERR_InvalidToken; VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_SetSystemStores); - if(sFlag) return CERR_InvalidInVirtualKeySection; - p += 5; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 5; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return CERR_InvalidToken; err = process_set_synonym(TSS_LAYER, fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; continue; - default: - return CERR_InvalidToken; - } - if(tokenFound) + default: + return CERR_InvalidToken; + } + if (tokenFound) { - *newp = p; - wcsncpy_s(output, max, tstr, max); // I3481 - output[max-1] = 0; - ErrChr = 0; - return CERR_None; - } - if(mx >= max) return CERR_BufferOverflow; - } while(*p); + *newp = p; + wcsncpy_s(output, max, tstr, max); // I3481 + output[max - 1] = 0; + ErrChr = 0; + return CERR_None; + } + if (mx >= max) return CERR_BufferOverflow; + } while (*p); - if(!*token) + if (!*token) { - *newp = p; - wcsncpy_s(output, max, tstr, max); // I3481 - output[max-1] = 0; - ErrChr = 0; + *newp = p; + wcsncpy_s(output, max, tstr, max); // I3481 + output[max - 1] = 0; + ErrChr = 0; return CERR_None; } } __finally { - delete tstr; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer - GetXString is re-entrant with if() + delete[] tstr; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer - GetXString is re-entrant with if() } - return CERR_NoTokensFound; + return CERR_NoTokensFound; } DWORD process_if_synonym(DWORD dwSystemID, PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx); // I3430 @@ -2506,25 +2510,25 @@ DWORD process_if_synonym(DWORD dwSystemID, PFILE_KEYBOARD fk, LPWSTR q, LPWSTR t PWSTR r; - if((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) { - delete temp; - return msg; + delete temp; + return msg; } DWORD dwStoreID; - if((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) + if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) { delete temp; return msg; } tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) CODE_IFSYSTEMSTORE; - tstr[(*mx)++] = (WCHAR)(dwSystemID+1); // I4785 + tstr[(*mx)++] = (WCHAR)CODE_IFSYSTEMSTORE; + tstr[(*mx)++] = (WCHAR)(dwSystemID + 1); // I4785 tstr[(*mx)++] = 2; - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; delete[] temp; @@ -2537,66 +2541,66 @@ DWORD process_if(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) // I3431 /* if( <'='|'!='> ) */ DWORD i, code, not = FALSE; LPWSTR r = q, s = q; - while(*s && *s != L' ' && *s != L'!' && *s != L'=') s++; + while (*s && *s != L' ' && *s != L'!' && *s != L'=') s++; r = s; - while(*s == L' ') s++; - if(*s == L'!') + while (*s == L' ') s++; + if (*s == L'!') { s++; not = TRUE; } - if(*s != '=') return CERR_InvalidIf; + if (*s != '=') return CERR_InvalidIf; s++; - while(*s == ' ') s++; + while (*s == ' ') s++; *r = 0; r = q; - if(r[0] == '&') + if (r[0] == '&') { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); - for(i = 0; StoreTokens[i]; i++) - { - if(_wcsicmp(r, StoreTokens[i]) == 0) break; - } - if(!StoreTokens[i]) return CERR_IfSystemStore_NotFound; + for (i = 0; StoreTokens[i]; i++) + { + if (_wcsicmp(r, StoreTokens[i]) == 0) break; + } + if (!StoreTokens[i]) return CERR_IfSystemStore_NotFound; code = CODE_IFSYSTEMSTORE; } else { - code = CODE_IFOPT; + code = CODE_IFOPT; - for(i = 0; i < fk->cxStoreArray; i++) - { - if(_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; - CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); + for (i = 0; i < fk->cxStoreArray; i++) + { + if (_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); } PWCHAR temp = new WCHAR[GLOBAL_BUFSIZE]; DWORD msg; - if((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) { - delete[] temp; - return msg; + delete[] temp; + return msg; } DWORD dwStoreID; - if((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) + if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) { delete[] temp; return msg; } tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) code; - tstr[(*mx)++] = (WCHAR)(i+1); + tstr[(*mx)++] = (WCHAR)code; + tstr[(*mx)++] = (WCHAR)(i + 1); tstr[(*mx)++] = not ? 1 : 2; - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; return CERR_None; @@ -2606,16 +2610,16 @@ DWORD process_reset(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) { /* reset() */ DWORD i; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = CODE_RESETOPT; - tstr[(*mx)++] = (WCHAR)(i+1); + tstr[(*mx)++] = (WCHAR)(i + 1); tstr[(*mx)] = 0; return CERR_None; @@ -2628,22 +2632,22 @@ DWORD process_set_synonym(DWORD dwSystemID, PFILE_KEYBOARD fk, LPWSTR q, LPWSTR PWCHAR temp = new WCHAR[GLOBAL_BUFSIZE], r; DWORD msg; - if((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) - { - delete temp; - return msg; - } + if ((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } DWORD dwStoreID; msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); - delete temp; - if(msg != CERR_None) return msg; + delete[] temp; + if (msg != CERR_None) return msg; tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) CODE_SETSYSTEMSTORE; - tstr[(*mx)++] = (WCHAR)(dwSystemID+1); - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)CODE_SETSYSTEMSTORE; + tstr[(*mx)++] = (WCHAR)(dwSystemID + 1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; return CERR_None; } @@ -2652,25 +2656,25 @@ DWORD process_set(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) { /* set( <'='> */ LPWSTR r = q, s = q; // I3440 - while(*s && *s != L' ' && *s != L'=') s++; + while (*s && *s != L' ' && *s != L'=') s++; r = s; - while(*s == L' ') s++; - if(*s != '=') return CERR_InvalidSet; + while (*s == L' ') s++; + if (*s != '=') return CERR_InvalidSet; s++; - while(*s == ' ') s++; + while (*s == ' ') s++; *r = 0; r = q; DWORD i, code; - if(r[0] == '&') + if (r[0] == '&') { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_SetSystemStores); // I3437 - for(i = 0; StoreTokens[i]; i++) - { - if(_wcsicmp(r, StoreTokens[i]) == 0) break; - } - if(!StoreTokens[i]) return CERR_SetSystemStore_NotFound; + for (i = 0; StoreTokens[i]; i++) + { + if (_wcsicmp(r, StoreTokens[i]) == 0) break; + } + if (!StoreTokens[i]) return CERR_SetSystemStore_NotFound; code = CODE_SETSYSTEMSTORE; } else @@ -2678,11 +2682,11 @@ DWORD process_set(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) wchar_t *context = NULL; LPWSTR r = wcstok_s(q, L" =", &context); // I3481 - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; + if (_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); code = CODE_SETOPT; } @@ -2693,22 +2697,22 @@ DWORD process_set(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) //r = wcstok(NULL, L" ="); - if((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) - { - delete temp; - return msg; - } + if ((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } DWORD dwStoreID; msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); - delete temp; - if(msg != CERR_None) return msg; + delete[] temp; + if (msg != CERR_None) return msg; tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) code; - tstr[(*mx)++] = (WCHAR)(i+1); - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)code; + tstr[(*mx)++] = (WCHAR)(i + 1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; return CERR_None; } @@ -2717,82 +2721,82 @@ DWORD process_save(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) { /* save() */ DWORD i; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = CODE_SAVEOPT; - tstr[(*mx)++] = (WCHAR)(i+1); + tstr[(*mx)++] = (WCHAR)(i + 1); tstr[(*mx)] = 0; return CERR_None; } int xatoi(PWSTR *p) { - PWSTR endptr; - int n; + PWSTR endptr; + int n; - switch(towupper(**p)) - { - case 'U': - (*p)++; - if(**p != '+') return 0; - (*p)++; - n = (int)wcstol(*p, &endptr, 16); - *p = endptr; - break; - case 'X': - (*p)++; - n = (int)wcstol(*p, &endptr, 16); - *p = endptr; - break; - case 'D': - (*p)++; - n = (int)wcstol(*p, &endptr, 10); - *p = endptr; - break; - default: - n = (int)wcstol(*p, &endptr, 8); - *p = endptr; - break; - } - return n; + switch (towupper(**p)) + { + case 'U': + (*p)++; + if (**p != '+') return 0; + (*p)++; + n = (int)wcstol(*p, &endptr, 16); + *p = endptr; + break; + case 'X': + (*p)++; + n = (int)wcstol(*p, &endptr, 16); + *p = endptr; + break; + case 'D': + (*p)++; + n = (int)wcstol(*p, &endptr, 10); + *p = endptr; + break; + default: + n = (int)wcstol(*p, &endptr, 8); + *p = endptr; + break; + } + return n; } int GetGroupNum(PFILE_KEYBOARD fk, PWSTR p) { - PFILE_GROUP gp; - DWORD i; + PFILE_GROUP gp; + DWORD i; - for(i = 0, gp = fk->dpGroupArray; i < fk->cxGroupArray; gp++, i++) - { - if(_wcsicmp(gp->szName, p) == 0) return i + 1; - } - return 0; + for (i = 0, gp = fk->dpGroupArray; i < fk->cxGroupArray; gp++, i++) + { + if (_wcsicmp(gp->szName, p) == 0) return i + 1; + } + return 0; } DWORD ProcessEthnologueStore(PWSTR p) // I2646 { DWORD res = CERR_None; - PWSTR q = NULL; - while(*p) + PWSTR q = NULL; + while (*p) { - while(wcschr(L" ,;", *p)) + while (wcschr(L" ,;", *p)) { - if(*p != ' ') res = CWARN_PunctuationInEthnologueCode; + if (*p != ' ') res = CWARN_PunctuationInEthnologueCode; p++; } - if(q == p) return CERR_InvalidEthnologueCode; - if(*p) + if (q == p) return CERR_InvalidEthnologueCode; + if (*p) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { - if(!iswalpha(*p)) return CERR_InvalidEthnologueCode; + if (!iswalpha(*p)) return CERR_InvalidEthnologueCode; p++; } } @@ -2805,13 +2809,13 @@ DWORD ProcessEthnologueStore(PWSTR p) // I2646 DWORD ProcessHotKey(PWSTR p, DWORD *hk) { - PWSTR q, r; - DWORD sFlag; - int j, i; + PWSTR q, r; + DWORD sFlag; + int j, i; - *hk = 0; + *hk = 0; - if(*p == UC_SENTINEL && *(p+1) == CODE_EXTENDED) { + if (*p == UC_SENTINEL && *(p + 1) == CODE_EXTENDED) { WORD Key = *(p + 3); WORD ShiftFlags = *(p + 2); @@ -2830,83 +2834,83 @@ DWORD ProcessHotKey(PWSTR p, DWORD *hk) return CERR_None; } - q = wcschr(p, '['); - if(q) + q = wcschr(p, '['); + if (q) + { + q++; + sFlag = 0; + + do { - q++; - sFlag = 0; + while (iswspace(*q)) q++; - do - { - while(iswspace(*q)) q++; + if (_wcsnicmp(q, L"ALT", 3) == 0) sFlag |= HK_ALT, q += 3; + else if (_wcsnicmp(q, L"CTRL", 4) == 0) sFlag |= HK_CTRL, q += 4; + else if (_wcsnicmp(q, L"SHIFT", 5) == 0) sFlag |= HK_SHIFT, q += 5; + else if (towupper(*q) != 'K') return CERR_InvalidToken; + } while (towupper(*q) != 'K'); - if(_wcsnicmp(q, L"ALT", 3) == 0) sFlag |= HK_ALT, q += 3; - else if(_wcsnicmp(q, L"CTRL", 4) == 0) sFlag |= HK_CTRL, q += 4; - else if(_wcsnicmp(q, L"SHIFT", 5) == 0) sFlag |= HK_SHIFT, q += 5; - else if(towupper(*q) != 'K') return CERR_InvalidToken; - } while(towupper(*q) != 'K'); - - r = wcschr(q, ']'); - if(r) - { - r--; - while(iswspace(*r) && r > q) r--; - r++; - } - else return CERR_NoTokensFound; - - j = (int)(INT_PTR) (r-q); - - for(i = 0; i <= VK__MAX; i++) // I3438 - if( j == (int)wcslen(VKeyNames[i]) && _wcsnicmp(q, VKeyNames[i], j) == 0) break; - - if(i == VK__MAX + 1) return CERR_InvalidToken; // I3438 - - *hk = i | sFlag; - - return CERR_None; - } - - q = GetDelimitedString(&p, L"\"\"", GDS_CUTLEAD | GDS_CUTFOLL); - if(q) + r = wcschr(q, ']'); + if (r) { - if(wcschr(q, '^')) *hk |= HK_CTRL; - if(wcschr(q, '+')) *hk |= HK_SHIFT; - if(wcschr(q, '%')) *hk |= HK_ALT; - q = wcschr(q, 0) - 1; - *hk |= *q; - return CERR_None; - } + r--; + while (iswspace(*r) && r > q) r--; + r++; + } + else return CERR_NoTokensFound; - return CERR_CodeInvalidInThisSection; + j = (int)(INT_PTR)(r - q); + + for (i = 0; i <= VK__MAX; i++) // I3438 + if (j == (int)wcslen(VKeyNames[i]) && _wcsnicmp(q, VKeyNames[i], j) == 0) break; + + if (i == VK__MAX + 1) return CERR_InvalidToken; // I3438 + + *hk = i | sFlag; + + return CERR_None; + } + + q = GetDelimitedString(&p, L"\"\"", GDS_CUTLEAD | GDS_CUTFOLL); + if (q) + { + if (wcschr(q, '^')) *hk |= HK_CTRL; + if (wcschr(q, '+')) *hk |= HK_SHIFT; + if (wcschr(q, '%')) *hk |= HK_ALT; + q = wcschr(q, 0) - 1; + *hk |= *q; + return CERR_None; + } + + return CERR_CodeInvalidInThisSection; } void SetChecksum(LPBYTE buf, LPDWORD CheckSum, DWORD sz) { - BuildCRCTable(); - *CheckSum = CalculateBufferCRC(buf, sz); + BuildCRCTable(); + *CheckSum = CalculateBufferCRC(buf, sz); } BOOL CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, BOOL fIsStore, BOOL fIsOption, BOOL fIsCall) { PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; - if(fIsStore && !sp->fIsStore) + if (fIsStore && !sp->fIsStore) { - if(sp->fIsDebug || sp->fIsOption || sp->fIsReserved || sp->fIsCall) + if (sp->fIsDebug || sp->fIsOption || sp->fIsReserved || sp->fIsCall) AddWarning(CWARN_StoreAlreadyUsedAsOptionOrCall); sp->fIsStore = TRUE; } - else if(fIsOption && !sp->fIsOption) + else if (fIsOption && !sp->fIsOption) { - if(sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsCall) + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsCall) AddWarning(CWARN_StoreAlreadyUsedAsStoreOrCall); sp->fIsOption = TRUE; } - else if(fIsCall && !sp->fIsCall) + else if (fIsCall && !sp->fIsCall) { - if(sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsOption) + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsOption) AddWarning(CWARN_StoreAlreadyUsedAsStoreOrOption); sp->fIsCall = TRUE; } @@ -2916,440 +2920,450 @@ BOOL CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, BOOL fIsStore, BOOL fIsO DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, HANDLE hOutfile) { - PFILE_GROUP fgp; - PFILE_STORE fsp; - PFILE_KEY fkp; + PFILE_GROUP fgp; + PFILE_STORE fsp; + PFILE_KEY fkp; - PCOMP_KEYBOARD ck; - PCOMP_GROUP gp; - PCOMP_STORE sp; - PCOMP_KEY kp; - PBYTE buf; - size_t offset; + PCOMP_KEYBOARD ck; + PCOMP_GROUP gp; + PCOMP_STORE sp; + PCOMP_KEY kp; + PBYTE buf; + size_t offset; size_t size; - DWORD i, j; + DWORD i, j; - // Calculate how much memory to allocate + // Calculate how much memory to allocate - size = sizeof(COMP_KEYBOARD) + - fk->cxGroupArray * sizeof(COMP_GROUP) + - fk->cxStoreArray * sizeof(COMP_STORE) + - /*wcslen(fk->szName)*2 + 2 + - wcslen(fk->szCopyright)*2 + 2 + - wcslen(fk->szLanguageName)*2 + 2 + - wcslen(fk->szMessage)*2 + 2 +*/ - fk->dwBitmapSize; + size = sizeof(COMP_KEYBOARD) + + fk->cxGroupArray * sizeof(COMP_GROUP) + + fk->cxStoreArray * sizeof(COMP_STORE) + + /*wcslen(fk->szName)*2 + 2 + + wcslen(fk->szCopyright)*2 + 2 + + wcslen(fk->szLanguageName)*2 + 2 + + wcslen(fk->szMessage)*2 + 2 +*/ + fk->dwBitmapSize; - for(i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) + for (i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) + { + if (FSaveDebug) size += wcslen(fgp->szName) * 2 + 2; + size += fgp->cxKeyArray * sizeof(COMP_KEY); + for (j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) { - if(FSaveDebug) size += wcslen(fgp->szName)*2 + 2; - size += fgp->cxKeyArray * sizeof(COMP_KEY); - for(j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) - { - size += wcslen(fkp->dpOutput)*2 + 2; - size += wcslen(fkp->dpContext)*2 + 2; - } + size += wcslen(fkp->dpOutput) * 2 + 2; + size += wcslen(fkp->dpContext) * 2 + 2; + } - if( fgp->dpMatch ) size += wcslen(fgp->dpMatch)*2 + 2; - if( fgp->dpNoMatch ) size += wcslen(fgp->dpNoMatch)*2 + 2; - } + if (fgp->dpMatch) size += wcslen(fgp->dpMatch) * 2 + 2; + if (fgp->dpNoMatch) size += wcslen(fgp->dpNoMatch) * 2 + 2; + } - for(i = 0; i < fk->cxStoreArray; i++) - { - size += wcslen(fk->dpStoreArray[i].dpString)*2 + 2; - if(FSaveDebug || fk->dpStoreArray[i].fIsOption) size += wcslen(fk->dpStoreArray[i].szName)*2 + 2; - } + for (i = 0; i < fk->cxStoreArray; i++) + { + size += wcslen(fk->dpStoreArray[i].dpString) * 2 + 2; + if (FSaveDebug || fk->dpStoreArray[i].fIsOption) size += wcslen(fk->dpStoreArray[i].szName) * 2 + 2; + } - buf = new BYTE[size]; - if(!buf) return CERR_CannotAllocateMemory; - memset(buf, 0, size); + buf = new BYTE[size]; + if (!buf) return CERR_CannotAllocateMemory; + memset(buf, 0, size); - ck = (PCOMP_KEYBOARD) buf; + ck = (PCOMP_KEYBOARD)buf; - ck->dwIdentifier = FILEID_COMPILED; + ck->dwIdentifier = FILEID_COMPILED; ck->dwFileVersion = fk->version; - ck->dwCheckSum = 0; // do checksum afterwards. - ck->KeyboardID = fk->KeyboardID; - ck->IsRegistered = TRUE; // I5135 - ck->cxStoreArray = fk->cxStoreArray; - ck->cxGroupArray = fk->cxGroupArray; - ck->StartGroup[0] = fk->StartGroup[0]; - ck->StartGroup[1] = fk->StartGroup[1]; - ck->dwHotKey = fk->dwHotKey; + ck->dwCheckSum = 0; // do checksum afterwards. + ck->KeyboardID = fk->KeyboardID; + ck->IsRegistered = TRUE; // I5135 + ck->cxStoreArray = fk->cxStoreArray; + ck->cxGroupArray = fk->cxGroupArray; + ck->StartGroup[0] = fk->StartGroup[0]; + ck->StartGroup[1] = fk->StartGroup[1]; + ck->dwHotKey = fk->dwHotKey; - ck->dwFlags = fk->dwFlags; + ck->dwFlags = fk->dwFlags; - offset = sizeof(COMP_KEYBOARD); + offset = sizeof(COMP_KEYBOARD); - /*ck->dpLanguageName = offset; - wcscpy((PWSTR)(buf + offset), fk->szLanguageName); - offset += wcslen(fk->szLanguageName)*2 + 2; + /*ck->dpLanguageName = offset; + wcscpy((PWSTR)(buf + offset), fk->szLanguageName); + offset += wcslen(fk->szLanguageName)*2 + 2; - ck->dpName = offset; - wcscpy((PWSTR)(buf + offset), fk->szName); - offset += wcslen(fk->szName)*2 + 2; + ck->dpName = offset; + wcscpy((PWSTR)(buf + offset), fk->szName); + offset += wcslen(fk->szName)*2 + 2; - ck->dpCopyright = offset; - wcscpy((PWSTR)(buf + offset), fk->szCopyright); - offset += wcslen(fk->szCopyright)*2 + 2; + ck->dpCopyright = offset; + wcscpy((PWSTR)(buf + offset), fk->szCopyright); + offset += wcslen(fk->szCopyright)*2 + 2; - ck->dpMessage = offset; - wcscpy((PWSTR)(buf + offset), fk->szMessage); - offset += wcslen(fk->szMessage)*2 + 2;*/ + ck->dpMessage = offset; + wcscpy((PWSTR)(buf + offset), fk->szMessage); + offset += wcslen(fk->szMessage)*2 + 2;*/ - ck->dpStoreArray = (DWORD) offset; - sp = (PCOMP_STORE)(buf+offset); - fsp = fk->dpStoreArray; - offset += sizeof(COMP_STORE) * ck->cxStoreArray; - for( i = 0; i < ck->cxStoreArray; i++, sp++, fsp++ ) + ck->dpStoreArray = (DWORD)offset; + sp = (PCOMP_STORE)(buf + offset); + fsp = fk->dpStoreArray; + offset += sizeof(COMP_STORE) * ck->cxStoreArray; + for (i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) + { + sp->dwSystemID = fsp->dwSystemID; + sp->dpString = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fsp->dpString); // I3481 // I3641 + offset += wcslen(fsp->dpString) * 2 + 2; + + if (FSaveDebug || fsp->fIsOption) { - sp->dwSystemID = fsp->dwSystemID; - sp->dpString = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fsp->dpString); // I3481 // I3641 - offset += wcslen(fsp->dpString)*2 + 2; + sp->dpName = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fsp->szName); // I3481 // I3641 + offset += wcslen(fsp->szName) * 2 + 2; + } + else sp->dpName = 0; + } - if(FSaveDebug || fsp->fIsOption) - { - sp->dpName = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fsp->szName); // I3481 // I3641 - offset += wcslen(fsp->szName)*2 + 2; - } - else sp->dpName = 0; - } + ck->dpGroupArray = (DWORD)offset; + gp = (PCOMP_GROUP)(buf + offset); + fgp = fk->dpGroupArray; - ck->dpGroupArray = (DWORD) offset; - gp = (PCOMP_GROUP)(buf+offset); - fgp = fk->dpGroupArray; + offset += sizeof(COMP_GROUP) * ck->cxGroupArray; - offset += sizeof(COMP_GROUP) * ck->cxGroupArray; + for (i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) + { + gp->cxKeyArray = fgp->cxKeyArray; + gp->fUsingKeys = fgp->fUsingKeys; - for(i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) + gp->dpMatch = gp->dpNoMatch = 0; + + if (fgp->dpMatch) { - gp->cxKeyArray = fgp->cxKeyArray; - gp->fUsingKeys = fgp->fUsingKeys; + gp->dpMatch = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fgp->dpMatch); // I3481 // I3641 + offset += wcslen(fgp->dpMatch) * 2 + 2; + } + if (fgp->dpNoMatch) + { + gp->dpNoMatch = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fgp->dpNoMatch); // I3481 // I3641 + offset += wcslen(fgp->dpNoMatch) * 2 + 2; + } - gp->dpMatch = gp->dpNoMatch = 0; + if (FSaveDebug) + { + gp->dpName = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fgp->szName); // I3481 // I3641 + offset += wcslen(fgp->szName) * 2 + 2; + } + else gp->dpName = 0; - if(fgp->dpMatch) - { - gp->dpMatch = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fgp->dpMatch); // I3481 // I3641 - offset += wcslen(fgp->dpMatch)*2 + 2; - } - if(fgp->dpNoMatch) - { - gp->dpNoMatch = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fgp->dpNoMatch); // I3481 // I3641 - offset += wcslen(fgp->dpNoMatch)*2 + 2; - } + gp->dpKeyArray = (DWORD)offset; + kp = (PCOMP_KEY)(buf + offset); + fkp = fgp->dpKeyArray; + offset += gp->cxKeyArray * sizeof(COMP_KEY); + for (j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) + { + kp->Key = fkp->Key; + if (FSaveDebug) kp->Line = fkp->Line; else kp->Line = 0; + kp->ShiftFlags = fkp->ShiftFlags; + kp->dpOutput = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fkp->dpOutput); // I3481 // I3641 + offset += wcslen(fkp->dpOutput) * 2 + 2; + kp->dpContext = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fkp->dpContext); // I3481 // I3641 + offset += wcslen(fkp->dpContext) * 2 + 2; + } + } - if(FSaveDebug) - { - gp->dpName = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fgp->szName); // I3481 // I3641 - offset += wcslen(fgp->szName)*2 + 2; - } - else gp->dpName = 0; + ck->dwBitmapSize = fk->dwBitmapSize; + ck->dpBitmapOffset = (DWORD)offset; + memcpy(buf + offset, fk->lpBitmap, fk->dwBitmapSize); + offset += fk->dwBitmapSize; - gp->dpKeyArray = (DWORD) offset; - kp = (PCOMP_KEY) (buf + offset); - fkp = fgp->dpKeyArray; - offset += gp->cxKeyArray * sizeof(COMP_KEY); - for(j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) - { - kp->Key = fkp->Key; - if(FSaveDebug) kp->Line = fkp->Line; else kp->Line = 0; - kp->ShiftFlags = fkp->ShiftFlags; - kp->dpOutput = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpOutput); // I3481 // I3641 - offset += wcslen(fkp->dpOutput)*2 + 2; - kp->dpContext = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpContext); // I3481 // I3641 - offset += wcslen(fkp->dpContext)*2 + 2; - } - } + if (offset != size) { + delete[] buf; + return CERR_SomewhereIGotItWrong; + } - ck->dwBitmapSize = fk->dwBitmapSize; - ck->dpBitmapOffset = (DWORD) offset; - memcpy(buf + offset, fk->lpBitmap, fk->dwBitmapSize); - offset += fk->dwBitmapSize; - - if(offset != size) return CERR_SomewhereIGotItWrong; - - SetChecksum(buf, &ck->dwCheckSum, (DWORD) size); + SetChecksum(buf, &ck->dwCheckSum, (DWORD)size); DWORD dwBytesWritten = 0; - WriteFile(hOutfile, buf, (DWORD) size, &dwBytesWritten, NULL); + WriteFile(hOutfile, buf, (DWORD)size, &dwBytesWritten, NULL); - if(dwBytesWritten != size) return CERR_UnableToWriteFully; + if (dwBytesWritten != size) { + delete[] buf; + return CERR_UnableToWriteFully; + } - delete buf; + delete[] buf; - return CERR_None; + return CERR_None; } DWORD ReadLine(HANDLE hInfile, PWSTR wstr, BOOL PreProcess) { - DWORD len; - PWSTR p; - BOOL LineCarry = FALSE, InComment = FALSE; - DWORD n; - WCHAR currentQuotes = 0; + DWORD len; + PWSTR p; + BOOL LineCarry = FALSE, InComment = FALSE; + DWORD n; + WCHAR currentQuotes = 0; WCHAR str[LINESIZE + 3]; - if(!ReadFile(hInfile, str, LINESIZE*2, &len, NULL)) return CERR_CannotReadInfile; - len /= 2; - str[len] = 0; + if (!ReadFile(hInfile, str, LINESIZE * 2, &len, NULL)) return CERR_CannotReadInfile; + len /= 2; + str[len] = 0; - if(SetFilePointer(hInfile, 0, NULL, FILE_CURRENT) == GetFileSize(hInfile, NULL)) - // Always a "\r\n" to the EOF, avoids funny bugs - wcscat_s(str, _countof(str), L"\r\n"); // I3481 + if (SetFilePointer(hInfile, 0, NULL, FILE_CURRENT) == GetFileSize(hInfile, NULL)) + // Always a "\r\n" to the EOF, avoids funny bugs + wcscat_s(str, _countof(str), L"\r\n"); // I3481 - if(len == 0) return CERR_EndOfFile; + if (len == 0) return CERR_EndOfFile; - for(p = str, n = 0; n < len; n++, p++) + for (p = str, n = 0; n < len; n++, p++) + { + if (currentQuotes != 0) { - if(currentQuotes != 0) - { - if( *p == L'\n' ) + if (*p == L'\n') { *p = 0; // I2525 - wcscpy_s(wstr, LINESIZE, str); // I3481 - return (PreProcess ? CERR_None : CERR_UnterminatedString); + wcscpy_s(wstr, LINESIZE, str); // I3481 + return (PreProcess ? CERR_None : CERR_UnterminatedString); + } + if (*p == currentQuotes) currentQuotes = 0; + continue; + } + if (InComment) { + if (*p == L'\n') break; + *p = L' '; + continue; + } + if (*p == L'\\') { + LineCarry = TRUE; + *p = L' '; + continue; + } + if (LineCarry) + { + switch (*p) + { + case L' ': + case L'\t': + case L'\r': + *p = L' '; + continue; + case L'\n': + currentLine++; + LineCarry = FALSE; + *p = L' '; + continue; } - if( *p == currentQuotes ) currentQuotes = 0; - continue; - } - if( InComment ) { - if( *p == L'\n' ) break; - *p = L' '; - continue; - } - if( *p == L'\\' ) { - LineCarry = TRUE; - *p = L' '; - continue; - } - if( LineCarry ) - { - switch( *p ) - { - case L' ': - case L'\t': - case L'\r': - *p = L' '; - continue; - case L'\n': - currentLine++; - LineCarry = FALSE; - *p = L' '; - continue; - } *p = 0; // I2525 wcscpy_s(wstr, LINESIZE, str); // I3481 - return (PreProcess ? CERR_None : CERR_InvalidLineContinuation); - } - - if( *p == L'\n' ) break; - switch( *p ) - { - case L'c': - case L'C': - if((p == str || iswspace(*(p-1))) && iswspace(*(p+1)) ) { - InComment = TRUE; - *p = L' '; - } - continue; - case L'\r': - case L'\t': - *p = L' '; - continue; - case L'\'': - case L'\"': - currentQuotes = *p; - continue; - } - } - - if( n == len ) - { - str[LINESIZE-1] = 0; // I2525 - wcscpy_s(wstr, LINESIZE, str); // I3481 - if(len == LINESIZE) - return (PreProcess ? CERR_None : CERR_LineTooLong); + return (PreProcess ? CERR_None : CERR_InvalidLineContinuation); } - if( *p == L'\n' ) currentLine++; + if (*p == L'\n') break; + switch (*p) + { + case L'c': + case L'C': + if ((p == str || iswspace(*(p - 1))) && iswspace(*(p + 1))) { + InComment = TRUE; + *p = L' '; + } + continue; + case L'\r': + case L'\t': + *p = L' '; + continue; + case L'\'': + case L'\"': + currentQuotes = *p; + continue; + } + } - SetFilePointer(hInfile, -(int)(len*2 - (INT_PTR)(p-str)*2 - 2), NULL, FILE_CURRENT); + if (n == len) + { + str[LINESIZE - 1] = 0; // I2525 + wcscpy_s(wstr, LINESIZE, str); // I3481 + if (len == LINESIZE) + return (PreProcess ? CERR_None : CERR_LineTooLong); + } - p--; - while(p >= str && iswspace(*p)) p--; - p++; - *p++ = L'\n'; - *p = 0; - // trim spaces now, why not? + if (*p == L'\n') currentLine++; + + SetFilePointer(hInfile, -(int)(len * 2 - (INT_PTR)(p - str) * 2 - 2), NULL, FILE_CURRENT); + + p--; + while (p >= str && iswspace(*p)) p--; + p++; + *p++ = L'\n'; + *p = 0; + // trim spaces now, why not? wcscpy_s(wstr, LINESIZE, str); // I3481 - return CERR_None; + return CERR_None; } DWORD GetRHS(PFILE_KEYBOARD fk, PWSTR p, PWSTR buf, int bufsize, int offset, int IsUnicode) { - PWSTR q; + PWSTR q; - p = wcschr(p, '>'); + p = wcschr(p, '>'); - if(!p) return CERR_NoTokensFound; + if (!p) return CERR_NoTokensFound; - p++; + p++; - return GetXString(fk, p, L"c\n", buf, bufsize, offset, &q, TRUE, IsUnicode); + return GetXString(fk, p, L"c\n", buf, bufsize, offset, &q, TRUE, IsUnicode); } void safe_wcsncpy(PWSTR out, PWSTR in, int cbMax) { - wcsncpy_s(out, cbMax, in, cbMax - 1); // I3481 - out[cbMax-1] = 0; + wcsncpy_s(out, cbMax, in, cbMax - 1); // I3481 + out[cbMax - 1] = 0; } BOOL IsSameToken(PWSTR *p, PWSTR token) { - PWSTR q; - q = *p; - while(iswspace(*q)) q++; - if(_wcsnicmp(q, token, wcslen(token)) == 0) - { - q += wcslen(token); - while(iswspace(*q)) q++; - *p = q; - return TRUE; - } - return FALSE; + PWSTR q; + q = *p; + while (iswspace(*q)) q++; + if (_wcsnicmp(q, token, wcslen(token)) == 0) + { + q += wcslen(token); + while (iswspace(*q)) q++; + *p = q; + return TRUE; + } + return FALSE; } BOOL IsRelativePath(char *p) { - // Relative path (returns TRUE): - // ..\...\BITMAP.BMP - // PATH\BITMAP.BMP - // BITMAP.BMP + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP - // Semi-absolute path (returns FALSE): - // \...\BITMAP.BMP + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP - // Absolute path (returns FALSE): - // C:\...\BITMAP.BMP - // \\SERVER\SHARE\...\BITMAP.BMP + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP - if(*p == '\\') return FALSE; - if(*p && *(p+1) == ':') return FALSE; + if (*p == '\\') return FALSE; + if (*p && *(p + 1) == ':') return FALSE; - return TRUE; + return TRUE; } DWORD ImportBitmapFile(PFILE_KEYBOARD fk, PWSTR szName, PDWORD FileSize, PBYTE *Buf) { - HANDLE hFile; - char szNewName[260], *p; + HANDLE hFile; + char szNewName[260], *p; - p = wstrtostr(szName); + p = wstrtostr(szName); - if(IsRelativePath(p)) - { - strcpy_s(szNewName, _countof(szNewName), CompileDir); // I3481 - strcat_s(szNewName, _countof(szNewName), p); // I3481 - } - else - strcpy_s(szNewName, _countof(szNewName), p); // I3481 + if (IsRelativePath(p)) + { + strcpy_s(szNewName, _countof(szNewName), CompileDir); // I3481 + strcat_s(szNewName, _countof(szNewName), p); // I3481 + } + else + strcpy_s(szNewName, _countof(szNewName), p); // I3481 - hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile == INVALID_HANDLE_VALUE) - { - strcat_s(szNewName, _countof(szNewName), ".bmp"); // I3481 - hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile == INVALID_HANDLE_VALUE) return CERR_CannotReadBitmapFile; - } + hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + strcat_s(szNewName, _countof(szNewName), ".bmp"); // I3481 + hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) return CERR_CannotReadBitmapFile; + } - delete p; + delete[] p; - *FileSize = GetFileSize(hFile, NULL); + *FileSize = GetFileSize(hFile, NULL); - if(*FileSize < 2) return CERR_CannotReadBitmapFile; + if (*FileSize < 2) return CERR_CannotReadBitmapFile; - *Buf = new BYTE[*FileSize]; + *Buf = new BYTE[*FileSize]; - if(!ReadFile(hFile, *Buf, *FileSize, FileSize, NULL)) return CERR_CannotReadBitmapFile; + if (!ReadFile(hFile, *Buf, *FileSize, FileSize, NULL)) { + delete[] * Buf; + *Buf = NULL; + return CERR_CannotReadBitmapFile; + } - CloseHandle(hFile); + CloseHandle(hFile); - /* Test for version 7.0 icon support */ + /* Test for version 7.0 icon support */ if (*((PCHAR)*Buf) != 'B' && *(((PCHAR)*Buf) + 1) != 'M') { VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); } - return CERR_None; + return CERR_None; } int atoiW(PWSTR p) { - PSTR q = wstrtostr(p); - int i = atoi(q); - delete q; - return i; + PSTR q = wstrtostr(p); + int i = atoi(q); + delete[] q; + return i; } int CheckUTF16(int n) { - const int res[] = { - 0xFDD0, 0xFDD1, 0xFDD2, 0xFDD3, 0xFDD4, 0xFDD5, 0xFDD6, 0xFDD7, - 0xFDD8, 0xFDD9, 0xFDDA, 0xFDDB, 0xFDDC, 0xFDDD, 0xFDDE, 0xFDDF, - 0xFDE0, 0xFDE1, 0xFDE2, 0xFDE3, 0xFDE4, 0xFDE5, 0xFDE6, 0xFDE7, - 0xFDE8, 0xFDE9, 0xFDEA, 0xFDEB, 0xFDEC, 0xFDED, 0xFDEE, 0xFDEF, - 0xFFFF, 0xFFFE, 0 }; + const int res[] = { + 0xFDD0, 0xFDD1, 0xFDD2, 0xFDD3, 0xFDD4, 0xFDD5, 0xFDD6, 0xFDD7, + 0xFDD8, 0xFDD9, 0xFDDA, 0xFDDB, 0xFDDC, 0xFDDD, 0xFDDE, 0xFDDF, + 0xFDE0, 0xFDE1, 0xFDE2, 0xFDE3, 0xFDE4, 0xFDE5, 0xFDE6, 0xFDE7, + 0xFDE8, 0xFDE9, 0xFDEA, 0xFDEB, 0xFDEC, 0xFDED, 0xFDEE, 0xFDEF, + 0xFFFF, 0xFFFE, 0 }; - if(n == 0) return CERR_ReservedCharacter; - for(int i = 0; res[i] > 0; i++) - if(n == res[i]) - { - AddWarning(CWARN_ReservedCharacter); - break; - } - return CERR_None; + if (n == 0) return CERR_ReservedCharacter; + for (int i = 0; res[i] > 0; i++) + if (n == res[i]) + { + AddWarning(CWARN_ReservedCharacter); + break; + } + return CERR_None; } int UTF32ToUTF16(int n, int *n1, int *n2) { - *n2 = -1; - if(n <= 0xFFFF) - { - *n1 = n; - if(n >= 0xD800 && n <= 0xDFFF) AddWarning(CWARN_UnicodeSurrogateUsed); - return CheckUTF16(*n1); - } + *n2 = -1; + if (n <= 0xFFFF) + { + *n1 = n; + if (n >= 0xD800 && n <= 0xDFFF) AddWarning(CWARN_UnicodeSurrogateUsed); + return CheckUTF16(*n1); + } - if((n & 0xFFFF) == 0xFFFF || (n & 0xFFFF) == 0xFFFE) AddWarning(CWARN_ReservedCharacter); - if(n < 0 || n > 0x10FFFF) return CERR_InvalidCharacter; - n = n - 0x10000; - *n1 = (n/0x400)+0xD800; - *n2 = (n%0x400)+0xDC00; - if((n = CheckUTF16(*n1)) != CERR_None) return n; - return CheckUTF16(*n2); + if ((n & 0xFFFF) == 0xFFFF || (n & 0xFFFF) == 0xFFFE) AddWarning(CWARN_ReservedCharacter); + if (n < 0 || n > 0x10FFFF) return CERR_InvalidCharacter; + n = n - 0x10000; + *n1 = (n / 0x400) + 0xD800; + *n2 = (n % 0x400) + 0xDC00; + if ((n = CheckUTF16(*n1)) != CERR_None) return n; + return CheckUTF16(*n2); } DWORD BuildVKDictionary(PFILE_KEYBOARD fk) // I3438 { DWORD i; size_t len = 0; - if(fk->cxVKDictionary == 0) return CERR_None; - for(i = 0; i < fk->cxVKDictionary; i++) + if (fk->cxVKDictionary == 0) return CERR_None; + for (i = 0; i < fk->cxVKDictionary; i++) { len += wcslen(fk->dpVKDictionary[i].szName) + 1; } PWSTR storeval = new WCHAR[len], p = storeval; - for(i = 0; i < fk->cxVKDictionary; i++) + for (i = 0; i < fk->cxVKDictionary; i++) { - wcscpy_s(p, len - (size_t)(p-storeval), fk->dpVKDictionary[i].szName); // I3481 + wcscpy_s(p, len - (size_t)(p - storeval), fk->dpVKDictionary[i].szName); // I3481 p = wcschr(p, 0); *p = ' '; p++; @@ -3366,97 +3380,97 @@ DWORD BuildVKDictionary(PFILE_KEYBOARD fk) // I3438 int GetVKCode(PFILE_KEYBOARD fk, PWSTR p) // I3438 // TODO: Consolidate GetDeadKey and GetVKCode? { - DWORD i; + DWORD i; - for(i = 0; i < fk->cxVKDictionary; i++) - if(_wcsicmp(fk->dpVKDictionary[i].szName, p) == 0) - return i+VK__MAX+1; // 256 + for (i = 0; i < fk->cxVKDictionary; i++) + if (_wcsicmp(fk->dpVKDictionary[i].szName, p) == 0) + return i + VK__MAX + 1; // 256 - if(fk->cxVKDictionary % 10 == 0) - { - PFILE_VKDICTIONARY pvk = new FILE_VKDICTIONARY[fk->cxVKDictionary+10]; + if (fk->cxVKDictionary % 10 == 0) + { + PFILE_VKDICTIONARY pvk = new FILE_VKDICTIONARY[fk->cxVKDictionary + 10]; memcpy(pvk, fk->dpVKDictionary, fk->cxVKDictionary * sizeof(FILE_VKDICTIONARY)); delete fk->dpVKDictionary; fk->dpVKDictionary = pvk; - } - wcsncpy_s(fk->dpVKDictionary[fk->cxVKDictionary].szName, _countof(fk->dpVKDictionary[fk->cxVKDictionary].szName), p, SZMAX_VKDICTIONARYNAME); // I3481 - fk->dpVKDictionary[fk->cxVKDictionary].szName[SZMAX_VKDICTIONARYNAME-1] = 0; + } + wcsncpy_s(fk->dpVKDictionary[fk->cxVKDictionary].szName, _countof(fk->dpVKDictionary[fk->cxVKDictionary].szName), p, SZMAX_VKDICTIONARYNAME - 1); // I3481 + fk->dpVKDictionary[fk->cxVKDictionary].szName[SZMAX_VKDICTIONARYNAME - 1] = 0; - fk->cxVKDictionary++; - return fk->cxVKDictionary+VK__MAX; // 256-1 + fk->cxVKDictionary++; + return fk->cxVKDictionary + VK__MAX; // 256-1 } int GetDeadKey(PFILE_KEYBOARD fk, PWSTR p) { - DWORD i; + DWORD i; - for(i = 0; i < fk->cxDeadKeyArray; i++) - if(_wcsicmp(fk->dpDeadKeyArray[i].szName, p) == 0) - return i+1; + for (i = 0; i < fk->cxDeadKeyArray; i++) + if (_wcsicmp(fk->dpDeadKeyArray[i].szName, p) == 0) + return i + 1; - if(fk->cxDeadKeyArray % 10 == 0) - { - PFILE_DEADKEY dk = new FILE_DEADKEY[fk->cxDeadKeyArray+10]; - memcpy(dk, fk->dpDeadKeyArray, fk->cxDeadKeyArray * sizeof(FILE_DEADKEY)); - delete[] fk->dpDeadKeyArray; - fk->dpDeadKeyArray = dk; - } - wcsncpy_s(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName, _countof(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName), p, SZMAX_DEADKEYNAME); // I3481 - fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName[SZMAX_DEADKEYNAME-1] = 0; + if (fk->cxDeadKeyArray % 10 == 0) + { + PFILE_DEADKEY dk = new FILE_DEADKEY[fk->cxDeadKeyArray + 10]; + memcpy(dk, fk->dpDeadKeyArray, fk->cxDeadKeyArray * sizeof(FILE_DEADKEY)); + delete[] fk->dpDeadKeyArray; + fk->dpDeadKeyArray = dk; + } + wcsncpy_s(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName, _countof(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName), p, SZMAX_DEADKEYNAME); // I3481 + fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName[SZMAX_DEADKEYNAME - 1] = 0; - fk->cxDeadKeyArray++; - return fk->cxDeadKeyArray; + fk->cxDeadKeyArray++; + return fk->cxDeadKeyArray; } void RecordDeadkeyNames(PFILE_KEYBOARD fk) { - WCHAR buf[SZMAX_DEADKEYNAME + 16]; - DWORD i; - for(i = 0; i < fk->cxDeadKeyArray; i++) - { - swprintf(buf, _countof(buf), L"%ls%d %ls", DEBUGSTORE_DEADKEY, i, fk->dpDeadKeyArray[i].szName); // I3481 - AddDebugStore(fk, buf); - } + WCHAR buf[SZMAX_DEADKEYNAME + 16]; + DWORD i; + for (i = 0; i < fk->cxDeadKeyArray; i++) + { + swprintf(buf, _countof(buf), L"%ls%d %ls", DEBUGSTORE_DEADKEY, (int)i, fk->dpDeadKeyArray[i].szName); // I3481 + AddDebugStore(fk, buf); + } } BOOL IsValidCallStore(PFILE_STORE fs) { - int i; - PWSTR p; - for(i = 0, p = fs->dpString; *p; p++) - if(*p == ':') i++; - else if(!((*p >= 'a' && *p <= 'z') || - (*p >= 'A' && *p <= 'Z') || - (*p >= '0' && *p <= '9') || - *p == '.' || - *p == '_')) - return FALSE; + int i; + PWSTR p; + for (i = 0, p = fs->dpString; *p; p++) + if (*p == ':') i++; + else if (!((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '.' || + *p == '_')) + return FALSE; - return i == 1; + return i == 1; } HANDLE CreateTempFile() { - char szTempPathBuffer[MAX_PATH], szTempFileName[MAX_PATH]; // I3228 // I3510 - if(!GetTempPath(MAX_PATH, szTempPathBuffer)) return INVALID_HANDLE_VALUE; - if(!GetTempFileName(szTempPathBuffer, "kmx", 0, szTempFileName)) return INVALID_HANDLE_VALUE; // I3228 // I3510 - return CreateFile(szTempFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); + char szTempPathBuffer[MAX_PATH], szTempFileName[MAX_PATH]; // I3228 // I3510 + if (!GetTempPath(MAX_PATH, szTempPathBuffer)) return INVALID_HANDLE_VALUE; + if (!GetTempFileName(szTempPathBuffer, "kmx", 0, szTempFileName)) return INVALID_HANDLE_VALUE; // I3228 // I3510 + return CreateFile(szTempFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); } /////////////////// HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble) { - HANDLE hOutfile = CreateTempFile(); - if(hOutfile == INVALID_HANDLE_VALUE) // I3228 // I3510 + HANDLE hOutfile = CreateTempFile(); + if (hOutfile == INVALID_HANDLE_VALUE) // I3228 // I3510 { CloseHandle(hInfile); return INVALID_HANDLE_VALUE; } - PBYTE buf, p; - PWSTR outbuf, poutbuf; - DWORD len, len2; + PBYTE buf, p; + PWSTR outbuf, poutbuf; + DWORD len, len2; WCHAR prolog = 0xFEFF; WriteFile(hOutfile, &prolog, 2, &len2, NULL); @@ -3488,8 +3502,8 @@ HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble) // because we don't support HINT/INFO messages yet and we don't want // this to cause a blocking compile at this stage poutbuf = strtowstr((PSTR)buf); - WriteFile(hOutfile, poutbuf, (DWORD) wcslen(poutbuf) * 2, &len2, NULL); - delete poutbuf; + WriteFile(hOutfile, poutbuf, (DWORD)wcslen(poutbuf) * 2, &len2, NULL); + delete[] poutbuf; } else { WriteFile(hOutfile, outbuf, (DWORD)(INT_PTR)(poutbuf - outbuf) * 2, &len2, NULL); @@ -3498,10 +3512,10 @@ HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble) } CloseHandle(hInfile); - delete buf; - delete outbuf; - SetFilePointer(hOutfile, 2, NULL, FILE_BEGIN); - return hOutfile; + delete[] buf; + delete[] outbuf; + SetFilePointer(hOutfile, 2, NULL, FILE_BEGIN); + return hOutfile; } extern "C" void __declspec(dllexport) Keyman_Diagnostic(int mode) { diff --git a/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp b/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp index 0fc760d222..6fc9c00b41 100644 --- a/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp +++ b/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp @@ -172,18 +172,23 @@ BOOL NamedCodeConstants::LoadFile(const char *filename) void NamedCodeConstants::reindex() { - qsort(entries, nEntries, sizeof(NCCENTRY), sort_entries); + if (entries != NULL) { + qsort(entries, nEntries, sizeof(NCCENTRY), sort_entries); + } char c = '.', d; int i; for(i = 0; i < 128; i++) chrindexes[i] = -1; - for(i = 0; i < nEntries; i++) - { - d = toupper(entries[i].name[0]); - if(d != c && d >= 32 && d <= 127) - chrindexes[c = d] = i; - } + + if (entries != NULL) { + for (i = 0; i < nEntries; i++) + { + d = toupper(entries[i].name[0]); + if (d != c && d >= 32 && d <= 127) + chrindexes[c = d] = i; + } + } } int NamedCodeConstants::GetCode(const char *codename, DWORD *storeIndex) diff --git a/windows/src/developer/kmcmpdll/kcframe.cpp b/windows/src/developer/kmcmpdll/kcframe.cpp index 2d41947135..2a704c9d43 100644 --- a/windows/src/developer/kmcmpdll/kcframe.cpp +++ b/windows/src/developer/kmcmpdll/kcframe.cpp @@ -28,7 +28,7 @@ int WINAPI msgproc(int line, DWORD dwMsgCode, LPSTR szText) { - printf("line %d error %x %s\n", line, dwMsgCode, szText); + printf("line %d error %x %s\n", line, (unsigned int) dwMsgCode, szText); return 1; } diff --git a/windows/src/developer/kmcmpdll/kmcmpdll.h b/windows/src/developer/kmcmpdll/kmcmpdll.h index 19c1a27de1..88535f93e5 100644 --- a/windows/src/developer/kmcmpdll/kmcmpdll.h +++ b/windows/src/developer/kmcmpdll/kmcmpdll.h @@ -5,8 +5,8 @@ BOOL AddCompileString(LPSTR buf); BOOL AddCompileMessage(DWORD msg); -#define SetError(err) { if(AddCompileMessage(err)) return FALSE; } +#define SetError(err) { if(AddCompileMessage(err) || (err & (CERR_MEMORY|CERR_FATAL))) return FALSE; } #define AddWarning(warn) { if(AddCompileMessage(warn)) return FALSE; } extern BOOL FWarnDeprecatedCode; -extern int currentLine; \ No newline at end of file +extern int currentLine; diff --git a/windows/src/developer/kmcmpdll/versioning.cpp b/windows/src/developer/kmcmpdll/versioning.cpp index e1d7bfce5f..e805bfdef6 100644 --- a/windows/src/developer/kmcmpdll/versioning.cpp +++ b/windows/src/developer/kmcmpdll/versioning.cpp @@ -12,7 +12,7 @@ BOOL CheckKeyboardFinalVersion(PFILE_KEYBOARD fk) { fk->version = VERSION_60; // minimum version that we can be safe with } - wsprintf(buf, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (fk->version & 0xFF00) >> 8, fk->version & 0xFF); + wsprintf(buf, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (int)((fk->version & 0xFF00) >> 8), (int)(fk->version & 0xFF)); AddCompileString(buf); } From 1df49317c9eba06f3719b6fba7a9b599a3815e65 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 30 Sep 2020 14:50:22 +1000 Subject: [PATCH 05/20] fix(windows): coverity reports for mcompile --- .../src/engine/mcompile/mc_import_rules.cpp | 5 ++- windows/src/engine/mcompile/mc_kmxfile.cpp | 41 +++++++++++-------- .../src/engine/mcompile/mc_savekeyboard.cpp | 30 +++++++++----- windows/src/engine/mcompile/mcompile.cpp | 32 +++++++-------- 4 files changed, 62 insertions(+), 46 deletions(-) diff --git a/windows/src/engine/mcompile/mc_import_rules.cpp b/windows/src/engine/mcompile/mc_import_rules.cpp index 826dd7f621..403cbcd7f1 100644 --- a/windows/src/engine/mcompile/mc_import_rules.cpp +++ b/windows/src/engine/mcompile/mc_import_rules.cpp @@ -462,7 +462,7 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector *FDeadk Loader loader; WCHAR inputHKL[12]; - wsprintf(inputHKL, L"%08.8x", wcstol(kbid, NULL, 16)); + wsprintf(inputHKL, L"%08.8x", (unsigned int) wcstol(kbid, NULL, 16)); int cKeyboards = GetKeyboardLayoutList(0, NULL); HKL *rghkl = new HKL[cKeyboards]; @@ -470,6 +470,7 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector *FDeadk HKL hkl = LoadKeyboardLayout(inputHKL, KLF_NOTELLSHELL); if(hkl == NULL) { puts("Sorry, that keyboard does not seem to be valid."); + delete[] rghkl; return false; } @@ -595,6 +596,8 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector *FDeadk UnloadKeyboardLayout(hkl); } + delete[] rghkl; + //------------------------------------------------------------- // Now that we've collected the key data, we need to // translate it to kmx and append to the existing keyboard diff --git a/windows/src/engine/mcompile/mc_kmxfile.cpp b/windows/src/engine/mcompile/mc_kmxfile.cpp index c20f8053d0..99db7daf05 100644 --- a/windows/src/engine/mcompile/mc_kmxfile.cpp +++ b/windows/src/engine/mcompile/mc_kmxfile.cpp @@ -40,26 +40,31 @@ BOOL LoadKeyboard(LPWSTR fileName, LPKEYBOARD *lpKeyboard) { filebase = buf; - ReadFile(hFile, filebase, sz, &sz, NULL); + if(!ReadFile(hFile, filebase, sz, &sz, NULL)) { + Err(L"errReadFile"); + CloseHandle(hFile); + delete[] buf; + return FALSE; + } CloseHandle(hFile); if(!VerifyKeyboard(filebase, sz)) { Err(L"errVerifyKeyboard"); - delete buf; + delete[] buf; return FALSE; } kbp = FixupKeyboard(buf, filebase, sz); if(!kbp) { Err(L"errFixupKeyboard"); - delete buf; + delete[] buf; return FALSE; } - if(kbp->dwIdentifier != FILEID_COMPILED) { - Err(L"errNotFileID"); - delete buf; - return FALSE; + if(kbp->dwIdentifier != FILEID_COMPILED) { + Err(L"errNotFileID"); + delete[] buf; + return FALSE; } *lpKeyboard = kbp; @@ -93,7 +98,7 @@ LPKEYBOARD FixupKeyboard(PBYTE bufp, PBYTE base, DWORD dwFileSize) { } for(gp = kbp->dpGroupArray, cgp = (PCOMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) { - gp->dpName = StringOffset(base, cgp->dpName); + gp->dpName = StringOffset(base, cgp->dpName); gp->dpKeyArray = (LPKEY) (base + cgp->dpKeyArray); if(cgp->dpMatch != NULL) gp->dpMatch = (PWSTR) (base + cgp->dpMatch); if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PWSTR) (base + cgp->dpNoMatch); @@ -124,12 +129,12 @@ BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz) { PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD) filebase; PCOMP_STORE csp; - /* Check file version */ + /* Check file version */ - if(ckbp->dwFileVersion < VERSION_MIN || - ckbp->dwFileVersion > VERSION_MAX) { - /* Old or new version -- identify the desired program version */ - if(VerifyChecksum(filebase, sz)) { + if(ckbp->dwFileVersion < VERSION_MIN || + ckbp->dwFileVersion > VERSION_MAX) { + /* Old or new version -- identify the desired program version */ + if(VerifyChecksum(filebase, sz)) { for(csp = (PCOMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) { if(csp->dwSystemID == TSS_COMPILEDVERSION) { wchar_t buf2[256]; @@ -144,12 +149,12 @@ BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz) { } } Err(L"errWrongFileVersion"); - return FALSE; + return FALSE; } - - if(!VerifyChecksum(filebase, sz)) { - Err(L"errBadChecksum"); - return FALSE; + + if(!VerifyChecksum(filebase, sz)) { + Err(L"errBadChecksum"); + return FALSE; } return TRUE; diff --git a/windows/src/engine/mcompile/mc_savekeyboard.cpp b/windows/src/engine/mcompile/mc_savekeyboard.cpp index bd8ac1beeb..35acde8b64 100644 --- a/windows/src/engine/mcompile/mc_savekeyboard.cpp +++ b/windows/src/engine/mcompile/mc_savekeyboard.cpp @@ -45,11 +45,11 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug) // Calculate how much memory to allocate - size = sizeof(COMP_KEYBOARD) + - fk->cxGroupArray * sizeof(COMP_GROUP) + + size = sizeof(COMP_KEYBOARD) + + fk->cxGroupArray * sizeof(COMP_GROUP) + fk->cxStoreArray * sizeof(COMP_STORE) + - /*wcslen(fk->szName)*2 + 2 + - wcslen(fk->szCopyright)*2 + 2 + + /*wcslen(fk->szName)*2 + 2 + + wcslen(fk->szCopyright)*2 + 2 + wcslen(fk->szLanguageName)*2 + 2 + wcslen(fk->szMessage)*2 + 2 +*/ fk->dwBitmapSize; @@ -62,7 +62,7 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug) size += wcslen(fkp->dpOutput)*2 + 2; size += wcslen(fkp->dpContext)*2 + 2; } - + if( fgp->dpMatch ) size += wcslen(fgp->dpMatch)*2 + 2; if( fgp->dpNoMatch ) size += wcslen(fgp->dpNoMatch)*2 + 2; } @@ -91,7 +91,7 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug) ck->StartGroup[0] = fk->StartGroup[0]; ck->StartGroup[1] = fk->StartGroup[1]; ck->dwHotKey = fk->dwHotKey; - + ck->dwFlags = fk->dwFlags; offset = sizeof(COMP_KEYBOARD); @@ -168,12 +168,12 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug) offset += gp->cxKeyArray * sizeof(COMP_KEY); for(j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) { kp->Key = fkp->Key; - kp->Line = fkp->Line; + kp->Line = fkp->Line; kp->ShiftFlags = fkp->ShiftFlags; kp->dpOutput = offset; wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpOutput); // I3481 // I3641 offset += wcslen(fkp->dpOutput)*2 + 2; - + kp->dpContext = offset; wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpContext); // I3481 // I3641 @@ -191,15 +191,23 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug) ck->dpBitmapOffset = 0; } - if(offset != size) return CERR_SomewhereIGotItWrong; + if(offset != size) + { + delete[] buf; + return CERR_SomewhereIGotItWrong; + } SetChecksum(buf, &ck->dwCheckSum, size); WriteFile(hOutfile, buf, size, &offset, NULL); - if(offset != size) return CERR_UnableToWriteFully; + if(offset != size) + { + delete[] buf; + return CERR_UnableToWriteFully; + } - delete buf; + delete[] buf; return CERR_None; } diff --git a/windows/src/engine/mcompile/mcompile.cpp b/windows/src/engine/mcompile/mcompile.cpp index c09a458fa8..c6a8299c89 100644 --- a/windows/src/engine/mcompile/mcompile.cpp +++ b/windows/src/engine/mcompile/mcompile.cpp @@ -1,18 +1,18 @@ /* Name: mcompile Copyright: Copyright (C) SIL International. - Documentation: - Description: + Documentation: + Description: Create Date: 24 Apr 2014 Modified Date: 8 Apr 2015 Authors: mcdurdin - Related Files: - Dependencies: + Related Files: + Dependencies: - Bugs: - Todo: - Notes: + Bugs: + Todo: + Notes: History: 24 Apr 2014 - mcdurdin - I4174 - V9 - mcompile logs should be stored in diag folder 16 Jun 2014 - mcdurdin - I4273 - V9.0 - Convert keyboards to Unicode before installing 23 Jun 2014 - mcdurdin - I4279 - V9.0 - mcompile fails to start when converting keyboard to Unicode @@ -82,7 +82,7 @@ int run(int argc, wchar_t * argv[]) } //DeleteReallocatedPointers(kmxfile); :TODO - delete kmxfile; + delete[] kmxfile; return 0; // I4279 } @@ -92,11 +92,11 @@ int run(int argc, wchar_t * argv[]) wchar_t *infile = argv[n], *indll = argv[n+1], *kbid = argv[n+2], *outfile = argv[n+3]; - wprintf(L"mcompile%s \"%s\" \"%s\" \"%s\" \"%s\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174 + wprintf(L"mcompile%s \"%ls\" \"%ls\" \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174 // 1. Load the keyman keyboard file - // 2. For each key on the system layout, determine its output character and perform a + // 2. For each key on the system layout, determine its output character and perform a // 1-1 replacement on the keyman keyboard of that character with the base VK + shift // state. This fixup will transform the char to a vk, which will avoid any issues // with the key. @@ -107,8 +107,8 @@ int run(int argc, wchar_t * argv[]) // rule for that deadkey, e.g. [K_LBRKT] > dk(c101) // // Next, update each rule that references the output from that deadkey to add an extra - // context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'. - // This will require a memory layout change for the .kmx file, plus fixups on the + // context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'. + // This will require a memory layout change for the .kmx file, plus fixups on the // context+output index offsets // // --> virtual character keys @@ -117,7 +117,7 @@ int run(int argc, wchar_t * argv[]) // switch the shift state from the VIRTUALCHARKEY to VIRTUALKEY, without changing any // other properties of the key. // - + // 3. Write the new keyman keyboard file if(!LoadNewLibrary(indll)) { @@ -167,7 +167,7 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT // // TranslateKey // -// For each key rule on the keyboard, remap its key to the +// For each key rule on the keyboard, remap its key to the // correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary // void TranslateKey(LPKEY key, WORD vk, UINT shift, WCHAR ch) { @@ -391,7 +391,7 @@ void ConvertDeadkey(LPKEYBOARD kbd, WORD vk, UINT shift, WCHAR deadkey) { GetDeadkeys(deadkey, pdk = deadkeys); // returns array of [usvk, ch_out] pairs while(*pdk) { - // Look up the ch + // Look up the ch UINT vkUnderlying = VKUnderlyingLayoutToVKUS(*pdk); TranslateDeadkeyKeyboard(kbd, dkid, vkUnderlying, *(pdk+1), *(pdk+2)); pdk+=3; @@ -435,7 +435,7 @@ BOOL DoConvert(LPKEYBOARD kbd, LPWSTR kbid, BOOL bDeadkeyConversion) { // I455 // Go through each possible key on the keyboard for(int i = 0; VKMap[i]; i++) { // I4651 UINT vkUnderlying = VKUSToVKUnderlyingLayout(VKMap[i]); - + WCHAR ch = CharFromVK(vkUnderlying, VKShiftState[j], &DeadKey); //LogError("--- VK_%d -> VK_%d [%c] dk=%d", VKMap[i], vkUnderlying, ch == 0 ? 32 : ch, DeadKey); From 146dd0acc5bd21675b8db2bdb5a98d4c7cbfc944 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 30 Sep 2020 14:53:47 +1000 Subject: [PATCH 06/20] fix: coverity reports for mcompile --- windows/src/engine/mcompile/mc_unicode.cpp | 6 +++--- windows/src/engine/mcompile/mcompile.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/windows/src/engine/mcompile/mc_unicode.cpp b/windows/src/engine/mcompile/mc_unicode.cpp index 93293326cd..bc86536f69 100644 --- a/windows/src/engine/mcompile/mc_unicode.cpp +++ b/windows/src/engine/mcompile/mc_unicode.cpp @@ -261,11 +261,11 @@ const WCHAR cp1252[256] = { void InplaceUnicode(PWSTR p) { while(p && *p) { if(*p != UC_SENTINEL) { - if(*p >= 0 && *p <= 0xFF) { + if(*p <= 0xFF) { *p = cp1252[*p]; } } - + p = incxstr(p); } } @@ -276,7 +276,7 @@ BOOL ConvertKeyboardToUnicode(LPKEYBOARD kbd) { LPKEY kp; DWORD i, j; - if(kbd->StartGroup[BEGIN_UNICODE] >= 0 && kbd->StartGroup[BEGIN_UNICODE] < kbd->cxGroupArray) { + if(kbd->StartGroup[BEGIN_UNICODE] < kbd->cxGroupArray) { // Keyboard is already Unicode return TRUE; } diff --git a/windows/src/engine/mcompile/mcompile.cpp b/windows/src/engine/mcompile/mcompile.cpp index c6a8299c89..06e79bd44c 100644 --- a/windows/src/engine/mcompile/mcompile.cpp +++ b/windows/src/engine/mcompile/mcompile.cpp @@ -92,7 +92,7 @@ int run(int argc, wchar_t * argv[]) wchar_t *infile = argv[n], *indll = argv[n+1], *kbid = argv[n+2], *outfile = argv[n+3]; - wprintf(L"mcompile%s \"%ls\" \"%ls\" \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174 + wprintf(L"mcompile%ls \"%ls\" \"%ls\" \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174 // 1. Load the keyman keyboard file From f691946f1c04e965555747c50d2a046c86f7dcd5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 30 Sep 2020 17:20:36 +1000 Subject: [PATCH 07/20] fix(windows): coverity reports for kmtip --- windows/src/engine/kmtip/debug.cpp | 6 +++--- windows/src/engine/kmtip/inserttext.cpp | 4 ++-- windows/src/engine/kmtip/kmkey.cpp | 4 +++- windows/src/engine/kmtip/kmtip.cpp | 10 +++++++++- windows/src/engine/kmtip/register.cpp | 8 ++------ 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/windows/src/engine/kmtip/debug.cpp b/windows/src/engine/kmtip/debug.cpp index 4ba02ede37..eaa8578b5f 100644 --- a/windows/src/engine/kmtip/debug.cpp +++ b/windows/src/engine/kmtip/debug.cpp @@ -65,19 +65,19 @@ void InitDebugging() { VS_FIXEDFILEINFO *ffi; DWORD sz; UINT ffilen; - char *buf = new char[1024], fname[260]; + char fname[260]; GetModuleFileName(GetModuleHandle("kmtip.dll"), fname, 260); sz = GetFileVersionInfoSize(fname, 0); if (sz > 0) { - buf = new char[sz]; + char *buf = new char[sz]; GetFileVersionInfo(fname, 0, sz, buf); VerQueryValue(buf, "\\", (void **)&ffi, &ffilen); SendDebugMessageFormat(L"kmtip version: %d.%d.%d.%d", HIWORD(ffi->dwProductVersionMS), LOWORD(ffi->dwProductVersionMS), HIWORD(ffi->dwProductVersionLS), LOWORD(ffi->dwProductVersionLS)); - delete buf; // I2157 + delete[] buf; // I2157 } else { SendDebugMessage(L"kmtip version: damaged"); diff --git a/windows/src/engine/kmtip/inserttext.cpp b/windows/src/engine/kmtip/inserttext.cpp index ad329ec6a6..4ed11a2309 100644 --- a/windows/src/engine/kmtip/inserttext.cpp +++ b/windows/src/engine/kmtip/inserttext.cpp @@ -1,4 +1,4 @@ -/* +/* Name: inserttext Copyright: Copyright (C) SIL International. Documentation: @@ -268,7 +268,7 @@ BOOL GetLeftOfSelection(TfEditCookie ec, ITfContext *pContext, WCHAR *buf, LONG if(ShouldDebug()) { char *p = debugstr(buf); Log(L"GetLeftOfSelection(%d) = %hs [%d fetched]", n, p, cFetched); - delete p; + delete[] p; } #ifdef DEBUG_PSEUDO // I3607 DePseudofy(buf); // I3564 diff --git a/windows/src/engine/kmtip/kmkey.cpp b/windows/src/engine/kmtip/kmkey.cpp index 0271a86172..aacb6cf768 100644 --- a/windows/src/engine/kmtip/kmkey.cpp +++ b/windows/src/engine/kmtip/kmkey.cpp @@ -56,6 +56,8 @@ public: _fUpdate = fUpdate; _fPreserved = fPreserved; // I3588 _dwDeepIntegration = dwDeepIntegration; // I4375 + _hr = S_FALSE; + _ec = 0; } // ITfEditSession @@ -245,7 +247,7 @@ HRESULT WINAPI CKeymanEditSession::KeymanProcessOutput(int n, WCHAR *buf, int nb if (ShouldDebug()) { char *p = debugstr(buf); SendDebugMessageFormat(L"KeymanProcessOutput: fUpdate = %d, deleting %d, inserting %d '%hs'", _fUpdate, n, nbuf, p); // I4262 - delete p; + delete[] p; } if (_fUpdate) { diff --git a/windows/src/engine/kmtip/kmtip.cpp b/windows/src/engine/kmtip/kmtip.cpp index 146603c78d..fb9194816b 100644 --- a/windows/src/engine/kmtip/kmtip.cpp +++ b/windows/src/engine/kmtip/kmtip.cpp @@ -79,6 +79,14 @@ CKMTipTextService::CKMTipTextService() // I3582 _dwThreadMgrEventSinkCookie = TF_INVALID_COOKIE; + memset(&guidActiveProfile, 0, sizeof(GUID)); + _keystrokeSinkInitialized = FALSE; + _hKeyman = NULL; + _dwActiveLanguageProfileNotifySinkCookie = 0; + _PreservedKeys = NULL; + _cPreservedKeyCount = 0; + _dwDeepIntegration = 0; + _cRef = 1; ThreadThis = this; } @@ -283,4 +291,4 @@ STDAPI CKMTipTextService::Deactivate() _tfClientId = TF_CLIENTID_NULL; return S_OK; -} \ No newline at end of file +} diff --git a/windows/src/engine/kmtip/register.cpp b/windows/src/engine/kmtip/register.cpp index f0e4fb8af2..0102432ea4 100644 --- a/windows/src/engine/kmtip/register.cpp +++ b/windows/src/engine/kmtip/register.cpp @@ -72,16 +72,12 @@ BOOL CKMTipTextService::RegisterProfiles() hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, (void**)&pInputProcessProfiles); - if (hr != S_OK) + if (hr != S_OK || pInputProcessProfiles == NULL) return FALSE; hr = pInputProcessProfiles->Register(c_clsidKMTipTextService); - if (hr != S_OK) - goto Exit; -Exit: - if(pInputProcessProfiles != NULL) // I2794 - pInputProcessProfiles->Release(); + pInputProcessProfiles->Release(); return (hr == S_OK); #endif From f63831374fdf3ecaccd10b7f43dc15657fe50f7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2020 17:29:43 +0000 Subject: [PATCH 08/20] chore(deps): bump @actions/core in /resources/build/version Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.2.2 to 1.2.6. - [Release notes](https://github.com/actions/toolkit/releases) - [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core) Signed-off-by: dependabot[bot] --- resources/build/version/package-lock.json | 6 +++--- resources/build/version/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/build/version/package-lock.json b/resources/build/version/package-lock.json index c5a26cbfae..2fcb0a27ae 100644 --- a/resources/build/version/package-lock.json +++ b/resources/build/version/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@actions/core": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.2.tgz", - "integrity": "sha512-IbCx7oefq+Gi6FWbSs2Fnw8VkEI6Y4gvjrYprY3RV//ksq/KPMlClOerJ4jRosyal6zkUIc8R9fS/cpRMlGClg==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz", + "integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==" }, "@actions/github": { "version": "2.1.0", diff --git a/resources/build/version/package.json b/resources/build/version/package.json index a7c7bfa5c8..51c3f13885 100644 --- a/resources/build/version/package.json +++ b/resources/build/version/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "@actions/core": "^1.2.2", + "@actions/core": "^1.2.6", "@actions/github": "^2.1.0", "typescript": "^3.7.5", "yargs": "^15.1.0" From 50ad8335ef3a1fc6b4f900b211ea0f7e9e557dc1 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 2 Oct 2020 09:18:49 +1000 Subject: [PATCH 09/20] Apply suggestions from code review Co-authored-by: Joshua Horton --- windows/src/developer/kmcmpdll/Compiler.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/windows/src/developer/kmcmpdll/Compiler.cpp b/windows/src/developer/kmcmpdll/Compiler.cpp index 4853fcd7e4..afeb7905c1 100644 --- a/windows/src/developer/kmcmpdll/Compiler.cpp +++ b/windows/src/developer/kmcmpdll/Compiler.cpp @@ -1303,8 +1303,7 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) wchar_t *pp = wcsrchr(p, L'\\'); if (!pp) { pp = p; - } - else { + } else { pp++; } q = new WCHAR[wcslen(pp) + 1]; @@ -1504,8 +1503,7 @@ DWORD CheckUseStatementsInOutput(PWSTR output) { // I4867 for (p = output; *p; p = incxstr(p)) { if (*p == UC_SENTINEL && *(p + 1) == CODE_USE) { HasUse = TRUE; - } - else if (HasUse) { + } else if (HasUse) { AddWarning(CWARN_UseNotLastStatementInRule); return FALSE; } @@ -1541,8 +1539,7 @@ DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PWSTR str, BOOL IsUnicode) if ((msg = GetXString(fk, str, L">", pklKey, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; if (pklKey[0] == 0) return CERR_ZeroLengthString; if (xstrlen(pklKey) > 1) AddWarning(CWARN_KeyBadLength); - } - else { + } else { if ((msg = GetXString(fk, str, L">", pklIn, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; if (pklIn[0] == 0) return CERR_ZeroLengthString; } From 0f9f7ec90db92ab8561c46e2c1aefdc0e139f14b Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 2 Oct 2020 10:55:58 +0700 Subject: [PATCH 10/20] fix(android/app): Switch system keyboard in KMPBrowserActivity --- .../kmapro/KMPBrowserActivity.java | 34 ++++++++++++++++++- .../kMAPro/src/main/res/values/strings.xml | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java index 3856db6ee4..78accf09f7 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java @@ -16,15 +16,18 @@ import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; +import android.widget.Toast; + import androidx.appcompat.app.AppCompatActivity; import com.tavultesoft.kmea.KMManager; +import com.tavultesoft.kmea.KeyboardEventHandler; import com.tavultesoft.kmea.util.KMPLink; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class KMPBrowserActivity extends AppCompatActivity { +public class KMPBrowserActivity extends AppCompatActivity implements KeyboardEventHandler.OnKeyboardEventListener { private static final String TAG = "KMPBrowserActivity"; // URL for keyboard search web page presented to user when they add a keyboard in the app. @@ -133,6 +136,8 @@ public class KMPBrowserActivity extends AppCompatActivity { @Override protected void onResume() { super.onResume(); + KMManager.addKeyboardEventListener(this); + if (webView != null) { webView.reload(); } @@ -141,6 +146,7 @@ public class KMPBrowserActivity extends AppCompatActivity { @Override protected void onPause() { super.onPause(); + KMManager.removeKeyboardEventListener(this); } @Override @@ -148,6 +154,32 @@ public class KMPBrowserActivity extends AppCompatActivity { super.onDestroy(); } + @Override + public void onKeyboardLoaded(KMManager.KeyboardType keyboardType) { + // Mitigation for https://github.com/keymanapp/keyman/issues/1963 + // Due to latency, switch from Keyman system keyboard to another + if (KMManager.getKMKeyboard(KMManager.KeyboardType.KEYBOARD_TYPE_SYSTEM) != null) { + Toast.makeText(getApplicationContext(), getString(R.string.switching_keyboard), + Toast.LENGTH_SHORT).show(); + KMManager.advanceToNextInputMode(); + } + } + + @Override + public void onKeyboardChanged(String newKeyboard) { + // Do nothing + } + + @Override + public void onKeyboardShown() { + // + } + + @Override + public void onKeyboardDismissed() { + // Do nothing + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); diff --git a/android/KMAPro/kMAPro/src/main/res/values/strings.xml b/android/KMAPro/kMAPro/src/main/res/values/strings.xml index 46b4985070..52e2a3dc8c 100644 --- a/android/KMAPro/kMAPro/src/main/res/values/strings.xml +++ b/android/KMAPro/kMAPro/src/main/res/values/strings.xml @@ -112,6 +112,8 @@ (from keyboard package) + + Switching to another keyboard Select Keyboard Package From 0406cb1381c6c95d436aeeb33b115cf7f09c68dd Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 2 Oct 2020 14:54:43 +1000 Subject: [PATCH 11/20] fix(windows): coverity reports for keyman32 --- .../src/engine/keyman32/DebugEventTrace.cpp | 18 +++++------ windows/src/engine/keyman32/K32_load.cpp | 11 ++++--- windows/src/engine/keyman32/Keyman32.cpp | 27 +++++++++++------ windows/src/engine/keyman32/SharedBuffers.cpp | 1 + windows/src/engine/keyman32/addins.cpp | 20 ++++--------- windows/src/engine/keyman32/appint/aiTIP.cpp | 7 +++-- .../keyman32/appint/aiWin2000Unicode.cpp | 2 +- windows/src/engine/keyman32/appint/appint.cpp | 2 ++ windows/src/engine/keyman32/calldll.cpp | 8 ++--- windows/src/engine/keyman32/k32_dbg.cpp | 30 +++++++++---------- windows/src/engine/keyman32/k32_tsf.cpp | 3 ++ windows/src/engine/keyman32/keybd_shift.cpp | 3 ++ .../src/engine/keyman32/keyboardoptions.cpp | 2 +- .../src/engine/keyman32/kmhook_getmessage.cpp | 6 ++-- windows/src/engine/keyman32/kmprocess.cpp | 4 +-- .../src/engine/keyman32/selectkeyboard.cpp | 8 ++--- .../engine/keyman32/serialkeyeventserver.cpp | 23 +++++++++++++- windows/src/engine/keyman32/versioninfo.cpp | 12 ++++---- windows/src/global/vc/keymansentry.cpp | 6 ++-- 19 files changed, 116 insertions(+), 77 deletions(-) diff --git a/windows/src/engine/keyman32/DebugEventTrace.cpp b/windows/src/engine/keyman32/DebugEventTrace.cpp index d9e8bbb4e3..1cfa02b705 100644 --- a/windows/src/engine/keyman32/DebugEventTrace.cpp +++ b/windows/src/engine/keyman32/DebugEventTrace.cpp @@ -68,7 +68,7 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i WCHAR windowinfo[1024]; wsprintfW(windowinfo, DEBUG_PLATFORM_STRINGW TAB //"Platform" TAB - L"%s" TAB //"Process" TAB + L"%ls" TAB //"Process" TAB L"%x" TAB //"PID" TAB L"%x" TAB //"TID" TAB L"%x" TAB //"ShiftState" TAB @@ -77,15 +77,15 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i L"%x" TAB //"FocusHWND" TAB L"%8x" TAB //"ActiveHKL" TAB L"%hs:%d" TAB //"SourceFile" TAB - L"%s\n", //"Message" + L"%ls\n", //"Message" sProcessName, //"Process" TAB - pid, //"PID" TAB - tid, //"TID" TAB - shiftState, //"ShiftState" TAB - actualShiftState, // ActualShiftState TAB - tickCount, //"TickCount" TAB - gti.hwndFocus, //"FocusHWND" TAB - activeHKL, //"ActiveHKL" TAB + (unsigned int) pid, //"PID" TAB + (unsigned int) tid, //"TID" TAB + (unsigned int) shiftState, //"ShiftState" TAB + (unsigned int) actualShiftState, // ActualShiftState TAB + (int) tickCount, //"TickCount" TAB + (unsigned int) gti.hwndFocus, //"FocusHWND" TAB + (unsigned int) activeHKL, //"ActiveHKL" TAB file, line, //"SourceFile" TAB msg); //"Message" diff --git a/windows/src/engine/keyman32/K32_load.cpp b/windows/src/engine/keyman32/K32_load.cpp index cb8a131f11..fbdf59b308 100644 --- a/windows/src/engine/keyman32/K32_load.cpp +++ b/windows/src/engine/keyman32/K32_load.cpp @@ -47,7 +47,7 @@ BOOL GetKeyboardFileName(LPSTR kbname, LPSTR buf, int nbuf) if(!_td) return FALSE; if(_td->ForceFileName[0]) { - strncpy_s(buf, nbuf, _td->ForceFileName, nbuf); + strncpy_s(buf, nbuf, _td->ForceFileName, nbuf - 1); buf[nbuf-1] = 0; return TRUE; } @@ -84,7 +84,7 @@ BOOL LoadlpKeyboard(int i) if(_td->lpActiveKeyboard == &_td->lpKeyboards[i]) _td->lpActiveKeyboard = NULL; // I822 TSF not working char buf[256]; - if(!GetKeyboardFileName(_td->lpKeyboards[i].Name, buf, 256)) return FALSE; + if(!GetKeyboardFileName(_td->lpKeyboards[i].Name, buf, 255)) return FALSE; if(!LoadKeyboard(buf, &_td->lpKeyboards[i].Keyboard)) return FALSE; // I5136 @@ -205,11 +205,14 @@ BOOL LoadKeyboard(LPSTR fileName, LPKEYBOARD *lpKeyboard) CloseHandle(hFile); PKEYMAN64THREADDATA _td = ThreadGlobals(); - if(!_td) return FALSE; + if (!_td) { + delete[] buf; + return FALSE; + } if(*LPDWORD(filebase) != FILEID_COMPILED) { - delete buf; + delete[] buf; Err("Invalid file"); return FALSE; } diff --git a/windows/src/engine/keyman32/Keyman32.cpp b/windows/src/engine/keyman32/Keyman32.cpp index f8e9aab9ce..1a3945b53e 100644 --- a/windows/src/engine/keyman32/Keyman32.cpp +++ b/windows/src/engine/keyman32/Keyman32.cpp @@ -246,10 +246,17 @@ void DoCWMF(UINT msg) void DoChangeWindowMessageFilter() { - PChangeWindowMessageFilter = (BOOL (WINAPI *)(UINT,DWORD))GetProcAddress(LoadLibrary("user32"), "ChangeWindowMessageFilter"); + HMODULE hUser32 = LoadLibrary("user32"); + if (!hUser32) + return; - if(!PChangeWindowMessageFilter) - return; + PChangeWindowMessageFilter = (BOOL (WINAPI *)(UINT,DWORD))GetProcAddress(hUser32, "ChangeWindowMessageFilter"); + + if (!PChangeWindowMessageFilter) + { + FreeLibrary(hUser32); + return; + } DoCWMF(wm_keyman); // I3594 DoCWMF(wm_keyman_keyevent); @@ -263,6 +270,8 @@ void DoChangeWindowMessageFilter() DoCWMF(wm_keymanshift); DoCWMF(wm_keyman_control); // I4714 DoCWMF(wm_keyman_control_internal); // I4714 + + FreeLibrary(hUser32); } BOOL InitThread(HWND hwnd) @@ -591,7 +600,7 @@ extern "C" BOOL _declspec(dllexport) WINAPI Keyman_ForceKeyboard(PCSTR FileName PKEYMAN64THREADDATA _td = ThreadGlobals(); if(!_td) return FALSE; - strncpy(_td->ForceFileName, FileName, MAX_PATH); + strncpy(_td->ForceFileName, FileName, MAX_PATH - 1); _td->ForceFileName[MAX_PATH-1] = 0; if(_td->lpActiveKeyboard) @@ -767,7 +776,7 @@ BOOL ConvertStringToGuid(WCHAR *buf, GUID *guid) // I3581 } void LoadBaseLayoutSettings() { // I4552 // I4583 - char underlyingLayout[16]; + char underlyingLayout[16] = ""; wchar_t baseLayout[MAX_PATH]; DWORD dwUnderlyingLayout = 0; @@ -776,7 +785,7 @@ void LoadBaseLayoutSettings() { // I4552 // I4583 if(reg->OpenKeyReadOnly(REGSZ_KeymanCU)) { if(reg->ReadString(REGSZ_UnderlyingLayout, underlyingLayout, 15)) { dwUnderlyingLayout = strtoul(underlyingLayout, NULL, 16); // I4516 // I4581 - wsprintf(underlyingLayout, "%08x", dwUnderlyingLayout); // I3759 // I4581 + wsprintf(underlyingLayout, "%08x", (unsigned int) dwUnderlyingLayout); // I3759 // I4581 } else { underlyingLayout[0] = 0; } @@ -797,7 +806,7 @@ void LoadBaseLayoutSettings() { // I4552 // I4583 if(GetLocaleInfoW(LOWORD(dwUnderlyingLayout), LOCALE_SISO639LANGNAME, langName, _countof(langName)) > 0 && GetLocaleInfoW(LOWORD(dwUnderlyingLayout), LOCALE_SISO3166CTRYNAME, countryName, _countof(countryName)) > 0) { // I4588 // I4786 - wsprintfW(baseLayoutAlt, L"%s-%s", langName, countryName); + wsprintfW(baseLayoutAlt, L"%ls-%ls", langName, countryName); Globals::SetBaseKeyboardName(baseLayout, baseLayoutAlt); } else { Globals::SetBaseKeyboardName(baseLayout, L"en-US"); // I4786 @@ -864,7 +873,7 @@ void RefreshKeyboards(BOOL Initialising) char oldname[_MAX_FNAME]; PKEYMAN64THREADDATA _td = ThreadGlobals(); - if(_td->FInRefreshKeyboards) return; + if(!_td || _td->FInRefreshKeyboards) return; _td->FInRefreshKeyboards = TRUE; // Can happen when multiple top-level windows for one process @@ -922,7 +931,7 @@ void RefreshKeyboards(BOOL Initialising) if(_td->lpKeyboards) { memcpy(kp, _td->lpKeyboards, sizeof(INTKEYBOARDINFO)*_td->nKeyboards); - delete _td->lpKeyboards; + delete[] _td->lpKeyboards; } _td->nKeyboards = nk + 1; _td->lpKeyboards = kp; diff --git a/windows/src/engine/keyman32/SharedBuffers.cpp b/windows/src/engine/keyman32/SharedBuffers.cpp index 1c52d03c6e..5b948d76fa 100644 --- a/windows/src/engine/keyman32/SharedBuffers.cpp +++ b/windows/src/engine/keyman32/SharedBuffers.cpp @@ -11,6 +11,7 @@ private: public: SharedBufferManager() { + m_pSharedData = NULL; m_hMMF = OpenFileMapping(FILE_MAP_READ, FALSE, GLOBAL_SHAREDBUFFER_FILE_MAPPING_NAME); if (!m_hMMF) { DebugLastError("OpenFileMapping"); diff --git a/windows/src/engine/keyman32/addins.cpp b/windows/src/engine/keyman32/addins.cpp index 1b0a65e7d2..6c7f5d0f28 100644 --- a/windows/src/engine/keyman32/addins.cpp +++ b/windows/src/engine/keyman32/addins.cpp @@ -38,7 +38,7 @@ void Addin_Release() if(_td->Addins[i].Uninitialise) (*_td->Addins[i].Uninitialise)(); FreeLibrary(_td->Addins[i].hAddin); } - delete _td->Addins; + delete[] _td->Addins; } _td->Addins = NULL; _td->nAddins = 0; @@ -56,14 +56,14 @@ void ReadAddins(HKEY hkey) if(reg->OpenKeyReadOnly(hkey == HKEY_CURRENT_USER ? REGSZ_KeymanAddinsCU : REGSZ_KeymanAddinsLM)) { int n = _td->nAddins; - char buf[128], buf2[512]; + char buf[128]; while(reg->GetValueNames(buf, 128, n)) { Addin *a = new Addin[n+1]; if(_td->Addins) { memcpy(a, _td->Addins, n * sizeof(Addin)); - delete _td->Addins; + delete[] _td->Addins; } _td->Addins = a; _td->Addins[n].hAddin = 0; @@ -74,17 +74,9 @@ void ReadAddins(HKEY hkey) _td->Addins[n].Uninitialise = NULL; _td->Addins[n].ShouldProcess = NULL; strcpy(_td->Addins[n].ClassName, buf); - reg->ReadString(buf, buf2, 512); - //char *p = strtok(buf2, ","); - //if(p) - //{ - _td->Addins[n].Application[0] = 0; - //strcpy(Addins[n].Application, p); - //p = strtok(NULL, ","); - strcpy(_td->Addins[n].AddinName, buf2); //p); - //SendDebugMessageFormat(GetFocus(), sdmGlobal, 0, "Addins: ReadAddins: App=%s Addin=%s %d", Addins[n].Application, Addins[n].AddinName, Addins[n].hAddin); - n++; - //} + reg->ReadString(buf, _td->Addins[n].AddinName, 260); + _td->Addins[n].Application[0] = 0; + n++; } _td->nAddins = n; } diff --git a/windows/src/engine/keyman32/appint/aiTIP.cpp b/windows/src/engine/keyman32/appint/aiTIP.cpp index d81f3b6030..bad49d28f1 100644 --- a/windows/src/engine/keyman32/appint/aiTIP.cpp +++ b/windows/src/engine/keyman32/appint/aiTIP.cpp @@ -259,6 +259,9 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM AITIP::AITIP() { ::AIWin2000Unicode(); // I3574 + FIsDebugControlWindow = FALSE; + useLegacy = FALSE; + WM_KEYMANDEBUG_CANDEBUG = RegisterWindowMessage("WM_KEYMANDEBUG_CANDEBUG"); WM_KEYMANDEBUG_GETUNICODESTATUS = RegisterWindowMessage("WM_KEYMANDEBUG_GETUNICODESTATUS"); WM_KEYMANDEBUG_GETCONTEXT = RegisterWindowMessage("WM_KEYMANDEBUG_GETCONTEXT"); @@ -548,7 +551,7 @@ BOOL AITIP::PostKeys() { SendDebugMessageFormat(0, sdmAIDefault, 0, "AITIP::PostKeys: no output"); } - delete OutBuf; // I4272 + delete[] OutBuf; // I4272 QueueSize = 0; return TRUE; @@ -643,7 +646,7 @@ void FillStoreOffsets(AIDEBUGINFO *di) if(n == MAXSTOREOFFSETS*2) break; } - if(n < MAXSTOREOFFSETS*2) + if(n < MAXSTOREOFFSETS*2 - 1) for(p = di->Rule->dpOutput; *p; p = incxstr(p)) { if(*p == UC_SENTINEL && *(p+1) == CODE_INDEX) diff --git a/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp b/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp index 4379e49971..b01227ca8f 100644 --- a/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp +++ b/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp @@ -303,7 +303,7 @@ BOOL AIWin2000Unicode::PostKeys() SendDebugMessageFormat(0, sdmAIDefault, 0, "App::PostKeys: sending input finished"); - delete pInputs; + delete[] pInputs; return TRUE; } diff --git a/windows/src/engine/keyman32/appint/appint.cpp b/windows/src/engine/keyman32/appint/appint.cpp index 0eace48036..018f3af806 100644 --- a/windows/src/engine/keyman32/appint/appint.cpp +++ b/windows/src/engine/keyman32/appint/appint.cpp @@ -160,6 +160,7 @@ BOOL AppContext::CharIsSurrogatePair() AppActionQueue::AppActionQueue() { + memset(Queue, 0, sizeof(APPACTIONQUEUEITEM) * MAXACTIONQUEUE); ResetQueue(); } @@ -192,4 +193,5 @@ BOOL AppActionQueue::QueueAction(int ItemType, DWORD dwData) AppIntegration::AppIntegration() { hwnd = NULL; + FShiftFlags = 0; } diff --git a/windows/src/engine/keyman32/calldll.cpp b/windows/src/engine/keyman32/calldll.cpp index c66cef968c..2db3fd6643 100644 --- a/windows/src/engine/keyman32/calldll.cpp +++ b/windows/src/engine/keyman32/calldll.cpp @@ -43,7 +43,7 @@ static LPIMDLL AddIMDLL(LPINTKEYBOARDINFO lpkbi, LPSTR kbdpath, LPSTR dllfilenam char drive[_MAX_DRIVE], dir[_MAX_DIR], fullname[_MAX_PATH], newdllname[_MAX_FNAME]; - strcpy(fullname, kbdpath); + strcpy_s(fullname, _countof(fullname), kbdpath); _splitpath_s(fullname, drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0); // I3547 #ifdef _WIN64 @@ -160,7 +160,7 @@ BOOL LoadDLLs(LPINTKEYBOARDINFO lpkbi) if(!q || !r) { s->dwSystemID = TSS_CALLDEFINITION_LOADFAILED; - delete p; + delete[] p; continue; } @@ -168,7 +168,7 @@ BOOL LoadDLLs(LPINTKEYBOARDINFO lpkbi) if(imd && AddIMDLLHook(imd, r, i, &s->dpString)) s->dwSystemID = TSS_CALLDEFINITION; else s->dwSystemID = TSS_CALLDEFINITION_LOADFAILED; - delete p; + delete[] p; } } @@ -225,7 +225,7 @@ void CallDLL(LPINTKEYBOARDINFO lpkbi, DWORD storenum) { //SendDebugMessageFormat(0, sdmKeyboard, 0, "CallDll: Enter"); - if(storenum < 0 || storenum >= lpkbi->Keyboard->cxStoreArray) return; + if(storenum >= lpkbi->Keyboard->cxStoreArray) return; LPSTORE s = &lpkbi->Keyboard->dpStoreArray[storenum]; if(s->dwSystemID != TSS_CALLDEFINITION) return; diff --git a/windows/src/engine/keyman32/k32_dbg.cpp b/windows/src/engine/keyman32/k32_dbg.cpp index d19a6cfbc5..a5757ee804 100644 --- a/windows/src/engine/keyman32/k32_dbg.cpp +++ b/windows/src/engine/keyman32/k32_dbg.cpp @@ -201,35 +201,35 @@ void DebugMessage(LPMSG msg, WPARAM wParam) // I2908 char ds[256]; if(msg->message == wm_keymankeydown) - wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd, - Debug_VirtualKey((WORD) msg->wParam), msg->lParam, wParam, msg->time); + wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", (unsigned int) msg->hwnd, + Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time); else if(msg->message == wm_keymankeyup) - wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd, - Debug_VirtualKey((WORD) msg->wParam), msg->lParam, wParam, msg->time); + wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", (unsigned int) msg->hwnd, + Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time); else if (msg->message == wm_keyman_keyevent) - wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd, - Debug_VirtualKey((WORD)msg->wParam), msg->lParam, wParam, msg->time); + wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", (unsigned int) msg->hwnd, + Debug_VirtualKey((WORD)msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time); else if(msg->message == WM_KEYDOWN || msg->message == WM_KEYUP || msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP) wsprintf(ds, "DebugMessage(%x, %s, wParam: %s, lParam: %X) [message flags: %x time: %d extra: %x]", - msg->hwnd, + (unsigned int) msg->hwnd, msgnames[msg->message-WM_KEYDOWN], Debug_VirtualKey((WORD) msg->wParam), - msg->lParam, + (unsigned int) msg->lParam, wParam, - msg->time, - GetMessageExtraInfo()); + (int) msg->time, + (unsigned int) GetMessageExtraInfo()); else if(msg->message >= WM_KEYDOWN && msg->message <= WM_UNICHAR) wsprintf(ds, "DebugMessage(%x, %s, wParam: '%c' (U+%04X), lParam: %X) [message flags: %x time: %d extra: %x]", - msg->hwnd, + (unsigned int) msg->hwnd, msgnames[msg->message-WM_KEYDOWN], msg->wParam, msg->wParam, - msg->lParam, + (unsigned int) msg->lParam, wParam, - msg->time, - GetMessageExtraInfo()); + (int) msg->time, + (unsigned int) GetMessageExtraInfo()); else - wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", msg->hwnd, msg->message, msg->wParam, msg->lParam, wParam, msg->time); + wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", (unsigned int) msg->hwnd, msg->message, msg->wParam, (unsigned int) msg->lParam, wParam, (int) msg->time); SendDebugMessage(msg->hwnd, sdmMessage, 0, ds); } diff --git a/windows/src/engine/keyman32/k32_tsf.cpp b/windows/src/engine/keyman32/k32_tsf.cpp index af888eb14d..9a1d404174 100644 --- a/windows/src/engine/keyman32/k32_tsf.cpp +++ b/windows/src/engine/keyman32/k32_tsf.cpp @@ -123,6 +123,9 @@ BOOL OpenTSF(PKEYMAN64THREADDATA _td) BOOL CloseTSF() { PKEYMAN64THREADDATA _td = ThreadGlobals(); + if (!_td) { + return FALSE; + } /*if(_td->dwSinkCookie != (DWORD)-1 && _td->pSource) { _td->pSource->UnadviseSink(_td->dwSinkCookie); diff --git a/windows/src/engine/keyman32/keybd_shift.cpp b/windows/src/engine/keyman32/keybd_shift.cpp index 5c94bf7041..37eeeb80f9 100644 --- a/windows/src/engine/keyman32/keybd_shift.cpp +++ b/windows/src/engine/keyman32/keybd_shift.cpp @@ -67,18 +67,21 @@ void do_keybd_event(LPINPUT pInputs, int *n, BYTE vk, BYTE scan, DWORD flags, UL switch(vk) { case VK_RCONTROL: flags |= KEYEVENTF_EXTENDEDKEY; + /*fallthrough*/ case VK_LCONTROL: vk = VK_CONTROL; break; case VK_RMENU: flags |= KEYEVENTF_EXTENDEDKEY; + /*fallthrough*/ case VK_LMENU: vk = VK_MENU; break; case VK_RSHIFT: scan = SCANCODE_RSHIFT; // from kbd.h + /*fallthrough*/ case VK_LSHIFT: vk = VK_SHIFT; break; diff --git a/windows/src/engine/keyman32/keyboardoptions.cpp b/windows/src/engine/keyman32/keyboardoptions.cpp index 1e0e0a8511..e0964cfd97 100644 --- a/windows/src/engine/keyman32/keyboardoptions.cpp +++ b/windows/src/engine/keyman32/keyboardoptions.cpp @@ -102,7 +102,7 @@ void ResetKeyboardOption(LPINTKEYBOARDINFO kp, int nStoreToReset) { if(r.ValueExists(kp->Keyboard->dpStoreArray[nStoreToReset].dpName)) { - WCHAR val[255]; + WCHAR val[256]; if(!r.ReadString(kp->Keyboard->dpStoreArray[nStoreToReset].dpName, val, sizeof(val) / sizeof(val[0]))) return; if(!val[0]) return; val[255] = 0; diff --git a/windows/src/engine/keyman32/kmhook_getmessage.cpp b/windows/src/engine/keyman32/kmhook_getmessage.cpp index a20b98888f..f58ac74f59 100644 --- a/windows/src/engine/keyman32/kmhook_getmessage.cpp +++ b/windows/src/engine/keyman32/kmhook_getmessage.cpp @@ -360,8 +360,8 @@ void ProcessWMKeyman(HWND hwnd, WPARAM wParam, LPARAM lParam) } SelectApplicationIntegration(); - if(!_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd); - _td->state.windowunicode = _td->app->IsUnicode(); + if(_td->app && !_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd); + _td->state.windowunicode = !_td->app || _td->app->IsUnicode(); if(IsFocusedThread()) { @@ -483,4 +483,4 @@ BOOL IsFocusedThread() } return gti.hwndFocus == GetFocus(); //return GetCurrentThreadId() == GetWindowThreadProcessId(GetForegroundWindow(), NULL); -} \ No newline at end of file +} diff --git a/windows/src/engine/keyman32/kmprocess.cpp b/windows/src/engine/keyman32/kmprocess.cpp index d1a3828f6b..d1f76e1b61 100644 --- a/windows/src/engine/keyman32/kmprocess.cpp +++ b/windows/src/engine/keyman32/kmprocess.cpp @@ -640,14 +640,14 @@ BOOL IsMatchingPlatform(LPSTORE s) // I3432 if(!IsMatchingPlatformString(platform)) { s->dwSystemID = TSS_PLATFORM_NOMATCH; - delete t; + delete[] t; return FALSE; } platform = wcstok_s(NULL, L" ", &context); } s->dwSystemID = TSS_PLATFORM_MATCH; - delete t; + delete[] t; return TRUE; } diff --git a/windows/src/engine/keyman32/selectkeyboard.cpp b/windows/src/engine/keyman32/selectkeyboard.cpp index b732f4daa2..0a0ae26613 100644 --- a/windows/src/engine/keyman32/selectkeyboard.cpp +++ b/windows/src/engine/keyman32/selectkeyboard.cpp @@ -104,8 +104,8 @@ BOOL SelectKeyboard(DWORD KeymanID) ResetCapsLock(); SelectApplicationIntegration(); // I4287 - if(!_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd); - _td->state.windowunicode = _td->app->IsUnicode(); + if(_td->app && !_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd); + _td->state.windowunicode = !_td->app || _td->app->IsUnicode(); ActivateDLLs(_td->lpActiveKeyboard); @@ -180,14 +180,14 @@ void SelectKeyboardHKL(PKEYMAN64THREADDATA _td, DWORD hkl, BOOL foreground) { } void PrepareLanguageSwitchString(UINT langid, HKL hkl, char *str) { - wsprintf(str, "%d|%d|%d", GetCurrentThreadId(), langid, hkl); // I4285 + wsprintf(str, "%d|%d|%d", (int) GetCurrentThreadId(), langid, (int) hkl); // I4285 } void PrepareLanguageSwitchString(UINT langid, GUID clsid, GUID guidProfile, char *str) { WCHAR clsidstr[40], profilestr[40]; StringFromGUID2(clsid, clsidstr, _countof(clsidstr)); StringFromGUID2(guidProfile, profilestr, _countof(profilestr)); - wsprintf(str, "%d|%d|%ws|%ws", GetCurrentThreadId(), langid, clsidstr, profilestr); // I4285 + wsprintf(str, "%d|%d|%ls|%ls", (int) GetCurrentThreadId(), langid, clsidstr, profilestr); // I4285 } void ReportActiveKeyboard(PKEYMAN64THREADDATA _td, WORD wCommand) { // I3933 // I3949 diff --git a/windows/src/engine/keyman32/serialkeyeventserver.cpp b/windows/src/engine/keyman32/serialkeyeventserver.cpp index a7682374f1..bf10694176 100644 --- a/windows/src/engine/keyman32/serialkeyeventserver.cpp +++ b/windows/src/engine/keyman32/serialkeyeventserver.cpp @@ -61,6 +61,18 @@ private: public: SerialKeyEventServer() { + m_idThread = 0; + m_hThread = NULL; + m_hThreadExitEvent = NULL; + memset(m_ModifierKeyboardState, 0, 256); + m_hKeyEvent = NULL; + m_hKeyMutex = NULL; + m_hMMF = NULL; + m_hwnd = NULL; + m_nInputs = 0; + m_pInputs = NULL; + m_pSharedData = NULL; + // We create the file mapping and global data on the main thread but release it on the // local thread. This ensures that these objects are available for other processes to // open even if we haven't completed startup of the local thread. @@ -102,6 +114,10 @@ public: DebugLastError("CloseHandle(m_hThreadExitEvent)"); } } + + // Normally, this is cleaned up by thread termination, but this + // handles error conditions better + CloseSharedData(); } virtual HWND GetWindow() const { @@ -170,21 +186,25 @@ private: DebugLastError("CloseHandle(m_hKeyMutex)"); bRet = FALSE; } + m_hKeyMutex = NULL; if (m_hKeyEvent != NULL && !CloseHandle(m_hKeyEvent)) { DebugLastError("CloseHandle(m_hKeyEvent)"); bRet = FALSE; } + m_hKeyEvent = NULL; if (m_pSharedData != NULL && !UnmapViewOfFile((LPCVOID)m_pSharedData)) { DebugLastError("CloseHandle(m_pSharedData)"); bRet = FALSE; } + m_pSharedData = NULL; if (m_hMMF != NULL && !CloseHandle(m_hMMF)) { DebugLastError("CloseHandle(m_hMMF)"); bRet = FALSE; } + m_hMMF = NULL; return bRet; } @@ -268,7 +288,8 @@ private: } if (m_pInputs != NULL) { - delete m_pInputs; + delete[] m_pInputs; + m_pInputs = NULL; } } diff --git a/windows/src/engine/keyman32/versioninfo.cpp b/windows/src/engine/keyman32/versioninfo.cpp index da906c98cf..07734f58b5 100644 --- a/windows/src/engine/keyman32/versioninfo.cpp +++ b/windows/src/engine/keyman32/versioninfo.cpp @@ -52,6 +52,8 @@ void GetWindowsVersion(char *buf) if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1 ) pos = "Microsoft Windows 7"; + // TODO: Update this for Win8, Win10, etc + // Test for product type. if ( osvi.wProductType == VER_NT_WORKSTATION ) @@ -77,16 +79,16 @@ void GetWindowsVersion(char *buf) if ( osvi.dwMajorVersion <= 4 ) { wsprintf (verinfo, "version %d.%d %s (Build %d)", - osvi.dwMajorVersion, - osvi.dwMinorVersion, + (int) osvi.dwMajorVersion, + (int) osvi.dwMinorVersion, osvi.szCSDVersion, - osvi.dwBuildNumber & 0xFFFF); + (int)(osvi.dwBuildNumber & 0xFFFF)); } else { wsprintf (verinfo, "version %s (Build %d)", osvi.szCSDVersion, - osvi.dwBuildNumber & 0xFFFF); + (int)(osvi.dwBuildNumber & 0xFFFF)); } break; @@ -121,6 +123,6 @@ void GetWindowsVersion(char *buf) break; } - wsprintf(buf, "Platform %s OS %s%s%s %s", pplatform, pos, pextra ? " " : "", pextra, verinfo); + wsprintf(buf, "Platform %s OS %s %s %s", pplatform, pos, *pextra ? " " : "", pextra, verinfo); } #pragma warning(default: 4996) diff --git a/windows/src/global/vc/keymansentry.cpp b/windows/src/global/vc/keymansentry.cpp index 090d0586af..f2a37332e2 100644 --- a/windows/src/global/vc/keymansentry.cpp +++ b/windows/src/global/vc/keymansentry.cpp @@ -50,7 +50,7 @@ int keyman_sentry_init(bool is_keyman_developer, const char *logger) { sentry_options_set_release(options, "release-" KEYMAN_VersionWithTag); // matches git tag sentry_options_set_environment(options, KEYMAN_Environment); // stable, beta, alpha, test, local - + // We don't currently need to set this, because it will be same path // as all our c++ executables. //sentry_options_set_handler_path(options, "path/to/crashpad_handler"); @@ -59,7 +59,7 @@ int keyman_sentry_init(bool is_keyman_developer, const char *logger) { if (RegOpenKeyExA(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey) == ERROR_SUCCESS) { DWORD dwType, dwValue, dwValueSize = 4; - g_report_exceptions = + g_report_exceptions = RegQueryValueExA(hkey, REGSZ_AutomaticallyReportErrors, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize) != ERROR_SUCCESS || dwType != REG_DWORD || dwValue != 0; dwValueSize = 4; @@ -133,7 +133,7 @@ void keyman_sentry_report_exception(DWORD ExceptionCode, PVOID ExceptionAddress) const int FRAMES_TO_SKIP = 0; char message[64]; - wsprintfA(message, "Exception %x at %p", ExceptionCode, ExceptionAddress); + wsprintfA(message, "Exception %x at %p", (unsigned int) ExceptionCode, ExceptionAddress); if (g_report_exceptions) { event = sentry_value_new_event(); From 3d00a2cbdab969b6805a06282c397bed9ce9dd96 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 2 Oct 2020 14:00:51 -0400 Subject: [PATCH 12/20] auto: increment master version to 14.0.154 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- .../web/input-processor/package-lock.json | 2 +- common/core/web/input-processor/package.json | 14 ++++++------- .../web/keyboard-processor/package-lock.json | 2 +- .../core/web/keyboard-processor/package.json | 10 +++++----- .../core/web/tools/recorder/package-lock.json | 2 +- common/core/web/tools/recorder/package.json | 10 +++++----- .../tools/sentry-manager/package-lock.json | 2 +- .../web/tools/sentry-manager/package.json | 4 ++-- common/core/web/utils/package-lock.json | 2 +- common/core/web/utils/package.json | 6 +++--- common/models/templates/package-lock.json | 2 +- common/models/templates/package.json | 8 ++++---- common/models/types/package-lock.json | 2 +- common/models/types/package.json | 2 +- common/models/wordbreakers/package-lock.json | 2 +- common/models/wordbreakers/package.json | 4 ++-- common/predictive-text/package-lock.json | 2 +- common/predictive-text/package.json | 14 ++++++------- developer/js/package-lock.json | 2 +- developer/js/package.json | 8 ++++---- lerna.json | 2 +- resources/gosh/package-lock.json | 2 +- resources/gosh/package.json | 2 +- resources/web-environment/package-lock.json | 2 +- resources/web-environment/package.json | 4 ++-- web/package-lock.json | 2 +- web/package.json | 20 +++++++++---------- 29 files changed, 73 insertions(+), 68 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 7121c8f3d2..6e68d3174d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 14.0.153 alpha 2020-10-02 + +* chore(deps): bump @actions/core from 1.2.2 to 1.2.6 in /resources/build/version (#3646) +* fix(android/app): Switch system keyboard in KMPBrowserActivity (#3648) + ## 14.0.152 alpha 2020-09-30 * fix(ios/engine): package installation language-picker improvements (#3623) diff --git a/VERSION.md b/VERSION.md index d6a5d3932e..d02cecea9f 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -14.0.153 \ No newline at end of file +14.0.154 \ No newline at end of file diff --git a/common/core/web/input-processor/package-lock.json b/common/core/web/input-processor/package-lock.json index 5c8c05e105..39fdfcfd73 100644 --- a/common/core/web/input-processor/package-lock.json +++ b/common/core/web/input-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/input-processor/package.json b/common/core/web/input-processor/package.json index 10b29b72ef..f15eac716e 100644 --- a/common/core/web/input-processor/package.json +++ b/common/core/web/input-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.153", + "version": "14.0.154", "description": "The core text and prediction processing engine for KeymanWeb", "repository": { "type": "git", @@ -18,7 +18,7 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.153", + "@keymanapp/resources-gosh": "^14.0.154", "chai": "^4.2.0", "mocha": "^5.2.0", "typescript": "^3.8.3" @@ -29,11 +29,11 @@ "test": "gosh ./unit_tests/test.sh" }, "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.153", - "@keymanapp/lexical-model-layer": "^14.0.153", - "@keymanapp/models-types": "^14.0.153", - "@keymanapp/web-environment": "^14.0.153", - "@keymanapp/web-utils": "^14.0.153", + "@keymanapp/keyboard-processor": "^14.0.154", + "@keymanapp/lexical-model-layer": "^14.0.154", + "@keymanapp/models-types": "^14.0.154", + "@keymanapp/web-environment": "^14.0.154", + "@keymanapp/web-utils": "^14.0.154", "@types/node": "^11.9.4", "eventemitter3": "^4.0.0", "ts-node": "^8.0.2" diff --git a/common/core/web/keyboard-processor/package-lock.json b/common/core/web/keyboard-processor/package-lock.json index 03745147ca..e70685f0b2 100644 --- a/common/core/web/keyboard-processor/package-lock.json +++ b/common/core/web/keyboard-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/keyboard-processor/package.json b/common/core/web/keyboard-processor/package.json index 61c42b05bf..22daeeaae1 100644 --- a/common/core/web/keyboard-processor/package.json +++ b/common/core/web/keyboard-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.153", + "version": "14.0.154", "description": "Core module for Keyman keyboard support in KeymanWeb.", "repository": { "type": "git", @@ -18,7 +18,7 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.153", + "@keymanapp/resources-gosh": "^14.0.154", "chai": "^4.2.0", "mocha": "^5.2.0", "mocha-teamcity-reporter": "^3.0.0", @@ -31,9 +31,9 @@ "mocha": "mocha" }, "dependencies": { - "@keymanapp/models-types": "^14.0.153", - "@keymanapp/web-environment": "^14.0.153", - "@keymanapp/web-utils": "^14.0.153", + "@keymanapp/models-types": "^14.0.154", + "@keymanapp/web-environment": "^14.0.154", + "@keymanapp/web-utils": "^14.0.154", "@types/node": "^11.9.4", "ts-node": "^8.0.2" } diff --git a/common/core/web/tools/recorder/package-lock.json b/common/core/web/tools/recorder/package-lock.json index 37e75af20c..31f672ff84 100644 --- a/common/core/web/tools/recorder/package-lock.json +++ b/common/core/web/tools/recorder/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/recorder/package.json b/common/core/web/tools/recorder/package.json index 4f8f9bb2bd..fd971b46ef 100644 --- a/common/core/web/tools/recorder/package.json +++ b/common/core/web/tools/recorder/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.153", + "version": "14.0.154", "description": "Core classes used to develop KeymanWeb test cases based on keystrokes", "main": "index.js", "scripts": { @@ -17,10 +17,10 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.153", - "@keymanapp/models-types": "^14.0.153", - "@keymanapp/web-environment": "^14.0.153", - "@keymanapp/web-utils": "^14.0.153" + "@keymanapp/keyboard-processor": "^14.0.154", + "@keymanapp/models-types": "^14.0.154", + "@keymanapp/web-environment": "^14.0.154", + "@keymanapp/web-utils": "^14.0.154" }, "devDependencies": { "typescript": "^3.8.3" diff --git a/common/core/web/tools/sentry-manager/package-lock.json b/common/core/web/tools/sentry-manager/package-lock.json index 49542541f2..e5d02ee011 100644 --- a/common/core/web/tools/sentry-manager/package-lock.json +++ b/common/core/web/tools/sentry-manager/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-sentry-manager", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/sentry-manager/package.json b/common/core/web/tools/sentry-manager/package.json index 5b2798e638..4bbf405e52 100644 --- a/common/core/web/tools/sentry-manager/package.json +++ b/common/core/web/tools/sentry-manager/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-sentry-manager", - "version": "14.0.153", + "version": "14.0.154", "description": "Common setup for KeymanWeb's Sentry-based error reporting", "main": "dist/index.js", "scripts": { @@ -20,7 +20,7 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/web-environment": "^14.0.153", + "@keymanapp/web-environment": "^14.0.154", "@sentry/browser": "^5.15.5" } } diff --git a/common/core/web/utils/package-lock.json b/common/core/web/utils/package-lock.json index 462df15f36..530e9edf62 100644 --- a/common/core/web/utils/package-lock.json +++ b/common/core/web/utils/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/utils/package.json b/common/core/web/utils/package.json index b3d8c6b118..eecda07c1b 100644 --- a/common/core/web/utils/package.json +++ b/common/core/web/utils/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.153", + "version": "14.0.154", "description": "Common utility functions used throughout other Keyman packages", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -20,8 +20,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.153", - "@keymanapp/web-environment": "^14.0.153", + "@keymanapp/resources-gosh": "^14.0.154", + "@keymanapp/web-environment": "^14.0.154", "@types/node": "^14.0.5", "typescript": "^3.8.3" } diff --git a/common/models/templates/package-lock.json b/common/models/templates/package-lock.json index 879d5ce7c3..77bdad0f3c 100644 --- a/common/models/templates/package-lock.json +++ b/common/models/templates/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-templates", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/templates/package.json b/common/models/templates/package.json index 587a84de63..11b06206ff 100644 --- a/common/models/templates/package.json +++ b/common/models/templates/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-templates", - "version": "14.0.153", + "version": "14.0.154", "description": "Backing model implementations (templates) for Keyman's modelling layer", "keywords": [ "lm", @@ -42,8 +42,8 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/models-types": "^14.0.153", - "@keymanapp/web-utils": "^14.0.153", + "@keymanapp/models-types": "^14.0.154", + "@keymanapp/web-utils": "^14.0.154", "@types/chai": "^4.2.11", "@types/mocha": "^7.0.2", "@types/node": "^14.0.4", @@ -52,6 +52,6 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/models-wordbreakers": "^14.0.153" + "@keymanapp/models-wordbreakers": "^14.0.154" } } diff --git a/common/models/types/package-lock.json b/common/models/types/package-lock.json index 2b45bfec80..debafef43d 100644 --- a/common/models/types/package-lock.json +++ b/common/models/types/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-types", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/types/package.json b/common/models/types/package.json index 81b7ac3d90..ea7c318a39 100644 --- a/common/models/types/package.json +++ b/common/models/types/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-types", - "version": "14.0.153", + "version": "14.0.154", "description": "Type definitions in used in the modeling (lexical model/predictive text) component of Keyman.", "types": "./index.d.ts", "scripts": { diff --git a/common/models/wordbreakers/package-lock.json b/common/models/wordbreakers/package-lock.json index 4d1865bf27..167b2503aa 100644 --- a/common/models/wordbreakers/package-lock.json +++ b/common/models/wordbreakers/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-wordbreakers", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/wordbreakers/package.json b/common/models/wordbreakers/package.json index 2436c68eed..f017356102 100644 --- a/common/models/wordbreakers/package.json +++ b/common/models/wordbreakers/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-wordbreakers", - "version": "14.0.153", + "version": "14.0.154", "description": "Word breakers bundled in the modeling layer", "keywords": [ "lexical model", @@ -40,7 +40,7 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/models-types": "^14.0.153", + "@keymanapp/models-types": "^14.0.154", "@types/chai": "^4.2.11", "@types/mocha": "^7.0.2", "chai": "^4.2.0", diff --git a/common/predictive-text/package-lock.json b/common/predictive-text/package-lock.json index fd9bd8d7e9..6035ee8a01 100644 --- a/common/predictive-text/package-lock.json +++ b/common/predictive-text/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/predictive-text/package.json b/common/predictive-text/package.json index 8ab942fc5a..257a299a58 100644 --- a/common/predictive-text/package.json +++ b/common/predictive-text/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.153", + "version": "14.0.154", "description": "Keyman/Predictive Text integration layer", "main": "build/index.js", "scripts": { @@ -21,8 +21,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/models-types": "^14.0.153", - "@keymanapp/resources-gosh": "^14.0.153", + "@keymanapp/models-types": "^14.0.154", + "@keymanapp/resources-gosh": "^14.0.154", "@types/node": "^10.17.21", "chai": "^4.2.0", "karma": "^4.2.0", @@ -46,10 +46,10 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/models-templates": "^14.0.153", - "@keymanapp/models-wordbreakers": "^14.0.153", - "@keymanapp/web-environment": "^14.0.153", - "@keymanapp/web-utils": "^14.0.153", + "@keymanapp/models-templates": "^14.0.154", + "@keymanapp/models-wordbreakers": "^14.0.154", + "@keymanapp/web-environment": "^14.0.154", + "@keymanapp/web-utils": "^14.0.154", "es6-shim": "^0.35.5", "string.prototype.codepointat": "^0.2.1", "string.prototype.startswith": "^0.2.0" diff --git a/developer/js/package-lock.json b/developer/js/package-lock.json index b305b08c4e..0b36609fa6 100644 --- a/developer/js/package-lock.json +++ b/developer/js/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-compiler", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/developer/js/package.json b/developer/js/package.json index dd39138a18..0d39273819 100644 --- a/developer/js/package.json +++ b/developer/js/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-compiler", - "version": "14.0.153", + "version": "14.0.154", "description": "Keyman Developer lexical model compiler", "keywords": [ "keyboard", @@ -37,14 +37,14 @@ "node": ">=12.0.0" }, "dependencies": { - "@keymanapp/models-types": "^14.0.153", + "@keymanapp/models-types": "^14.0.154", "commander": "^3.0.0", "typescript": "^3.8.3", "xml2js": "^0.4.19" }, "devDependencies": { - "@keymanapp/models-templates": "^14.0.153", - "@keymanapp/models-wordbreakers": "^14.0.153", + "@keymanapp/models-templates": "^14.0.154", + "@keymanapp/models-wordbreakers": "^14.0.154", "@types/chai": "^4.1.7", "@types/mocha": "^5.2.7", "@types/node": "^10.14.6", diff --git a/lerna.json b/lerna.json index 214aa59f39..5473bd4dcc 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "lerna", "typescript" ], - "version": "14.0.153" + "version": "14.0.154" } diff --git a/resources/gosh/package-lock.json b/resources/gosh/package-lock.json index 390cfe9676..884adea3a0 100644 --- a/resources/gosh/package-lock.json +++ b/resources/gosh/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1 } diff --git a/resources/gosh/package.json b/resources/gosh/package.json index 460adc1df2..f374935127 100644 --- a/resources/gosh/package.json +++ b/resources/gosh/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.153", + "version": "14.0.154", "description": "Good Ol' Shell", "author": "Marc Durdin (https://github.com/mcdurdin)", "contributors": [ diff --git a/resources/web-environment/package-lock.json b/resources/web-environment/package-lock.json index 653c9d058d..72f8bcc422 100644 --- a/resources/web-environment/package-lock.json +++ b/resources/web-environment/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/web-environment", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1 } diff --git a/resources/web-environment/package.json b/resources/web-environment/package.json index 285f3f581d..f85708fb76 100644 --- a/resources/web-environment/package.json +++ b/resources/web-environment/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-environment", - "version": "14.0.153", + "version": "14.0.154", "description": "A compilation utility for passing select environment variables into our TS builds", "author": "Joshua Horton (https://github.com/jahorton)", "homepage": "https://github.com/keymanapp/keyman", @@ -17,6 +17,6 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.153" + "@keymanapp/resources-gosh": "^14.0.154" } } diff --git a/web/package-lock.json b/web/package-lock.json index b2d898abe3..0a75da2b9c 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.153", + "version": "14.0.154", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/web/package.json b/web/package.json index 7d28c69248..dbb8898eee 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.153", + "version": "14.0.154", "description": "Facilitates text input in any language.", "repository": { "type": "git", @@ -18,8 +18,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.153", - "@keymanapp/web-sentry-manager": "^14.0.153", + "@keymanapp/resources-gosh": "^14.0.154", + "@keymanapp/web-sentry-manager": "^14.0.154", "@sentry/cli": "^1.52.3", "chai": "^4.2.0", "google-closure-compiler-java": "^20200224.0.0", @@ -52,13 +52,13 @@ "sentry-cli": "sentry-cli" }, "dependencies": { - "@keymanapp/input-processor": "^14.0.153", - "@keymanapp/keyboard-processor": "^14.0.153", - "@keymanapp/lexical-model-layer": "^14.0.153", - "@keymanapp/models-types": "^14.0.153", - "@keymanapp/recorder-core": "^14.0.153", - "@keymanapp/web-environment": "^14.0.153", - "@keymanapp/web-utils": "^14.0.153", + "@keymanapp/input-processor": "^14.0.154", + "@keymanapp/keyboard-processor": "^14.0.154", + "@keymanapp/lexical-model-layer": "^14.0.154", + "@keymanapp/models-types": "^14.0.154", + "@keymanapp/recorder-core": "^14.0.154", + "@keymanapp/web-environment": "^14.0.154", + "@keymanapp/web-utils": "^14.0.154", "@types/node": "^11.9.4", "es6-shim": "^0.35.5", "eventemitter3": "^4.0.0", From 7f70c14b2a1c8b42c2be4f58012cfb3f9953291f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 5 Oct 2020 09:30:55 +1100 Subject: [PATCH 13/20] fix(windows): Cast HANDLE types using PtrToInt --- windows/src/engine/keyman32/DebugEventTrace.cpp | 4 ++-- windows/src/engine/keyman32/k32_dbg.cpp | 12 ++++++------ windows/src/engine/keyman32/selectkeyboard.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/windows/src/engine/keyman32/DebugEventTrace.cpp b/windows/src/engine/keyman32/DebugEventTrace.cpp index 1cfa02b705..3ff479a3a6 100644 --- a/windows/src/engine/keyman32/DebugEventTrace.cpp +++ b/windows/src/engine/keyman32/DebugEventTrace.cpp @@ -84,8 +84,8 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i (unsigned int) shiftState, //"ShiftState" TAB (unsigned int) actualShiftState, // ActualShiftState TAB (int) tickCount, //"TickCount" TAB - (unsigned int) gti.hwndFocus, //"FocusHWND" TAB - (unsigned int) activeHKL, //"ActiveHKL" TAB + PtrToInt(gti.hwndFocus), //"FocusHWND" TAB + PtrToInt(activeHKL), //"ActiveHKL" TAB file, line, //"SourceFile" TAB msg); //"Message" diff --git a/windows/src/engine/keyman32/k32_dbg.cpp b/windows/src/engine/keyman32/k32_dbg.cpp index a5757ee804..b58eb8df85 100644 --- a/windows/src/engine/keyman32/k32_dbg.cpp +++ b/windows/src/engine/keyman32/k32_dbg.cpp @@ -201,17 +201,17 @@ void DebugMessage(LPMSG msg, WPARAM wParam) // I2908 char ds[256]; if(msg->message == wm_keymankeydown) - wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", (unsigned int) msg->hwnd, + wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd), Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time); else if(msg->message == wm_keymankeyup) - wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", (unsigned int) msg->hwnd, + wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd), Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time); else if (msg->message == wm_keyman_keyevent) - wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", (unsigned int) msg->hwnd, + wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd), Debug_VirtualKey((WORD)msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time); else if(msg->message == WM_KEYDOWN || msg->message == WM_KEYUP || msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP) wsprintf(ds, "DebugMessage(%x, %s, wParam: %s, lParam: %X) [message flags: %x time: %d extra: %x]", - (unsigned int) msg->hwnd, + PtrToInt(msg->hwnd), msgnames[msg->message-WM_KEYDOWN], Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, @@ -220,7 +220,7 @@ void DebugMessage(LPMSG msg, WPARAM wParam) // I2908 (unsigned int) GetMessageExtraInfo()); else if(msg->message >= WM_KEYDOWN && msg->message <= WM_UNICHAR) wsprintf(ds, "DebugMessage(%x, %s, wParam: '%c' (U+%04X), lParam: %X) [message flags: %x time: %d extra: %x]", - (unsigned int) msg->hwnd, + PtrToInt(msg->hwnd), msgnames[msg->message-WM_KEYDOWN], msg->wParam, msg->wParam, @@ -229,7 +229,7 @@ void DebugMessage(LPMSG msg, WPARAM wParam) // I2908 (int) msg->time, (unsigned int) GetMessageExtraInfo()); else - wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", (unsigned int) msg->hwnd, msg->message, msg->wParam, (unsigned int) msg->lParam, wParam, (int) msg->time); + wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", PtrToInt(msg->hwnd), msg->message, msg->wParam, (unsigned int) msg->lParam, wParam, (int) msg->time); SendDebugMessage(msg->hwnd, sdmMessage, 0, ds); } diff --git a/windows/src/engine/keyman32/selectkeyboard.cpp b/windows/src/engine/keyman32/selectkeyboard.cpp index 0a0ae26613..e207b5eb64 100644 --- a/windows/src/engine/keyman32/selectkeyboard.cpp +++ b/windows/src/engine/keyman32/selectkeyboard.cpp @@ -180,7 +180,7 @@ void SelectKeyboardHKL(PKEYMAN64THREADDATA _td, DWORD hkl, BOOL foreground) { } void PrepareLanguageSwitchString(UINT langid, HKL hkl, char *str) { - wsprintf(str, "%d|%d|%d", (int) GetCurrentThreadId(), langid, (int) hkl); // I4285 + wsprintf(str, "%d|%d|%d", (int) GetCurrentThreadId(), langid, PtrToInt(hkl)); // I4285 } void PrepareLanguageSwitchString(UINT langid, GUID clsid, GUID guidProfile, char *str) { From 41fb5296e42fa6241b6b412a64d16fac6a2f38a5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 5 Oct 2020 13:07:39 +1100 Subject: [PATCH 14/20] Update windows/src/developer/kmcmpdll/Compiler.cpp additional braces Co-authored-by: Joshua Horton --- windows/src/developer/kmcmpdll/Compiler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/windows/src/developer/kmcmpdll/Compiler.cpp b/windows/src/developer/kmcmpdll/Compiler.cpp index afeb7905c1..4eb236deaf 100644 --- a/windows/src/developer/kmcmpdll/Compiler.cpp +++ b/windows/src/developer/kmcmpdll/Compiler.cpp @@ -1481,10 +1481,10 @@ DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PWSTR context, PW int anyStore = *(q + 2) - 1; - if (xstrlen(fk->dpStoreArray[indexStore].dpString) < xstrlen(fk->dpStoreArray[anyStore].dpString)) + if (xstrlen(fk->dpStoreArray[indexStore].dpString) < xstrlen(fk->dpStoreArray[anyStore].dpString)) { AddWarning(CWARN_IndexStoreShort); - } - else if (*(p + 1) == CODE_CONTEXTEX) { + } + } else if (*(p + 1) == CODE_CONTEXTEX) { int contextOffset = *(p + 2); if (contextOffset > xstrlen(context)) return CERR_ContextExHasInvalidOffset; From ee52b40307d06f378ab1a7b65e1f152c592177da Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 5 Oct 2020 13:59:32 +1100 Subject: [PATCH 15/20] chore: exclude parens if no scope in commit msg If no scope is found in the branch name, then don't include the parentheses around the scope, as this breaks automatic merge messages and the parentheses are unnecessary. --- resources/git-hooks/prepare-commit-msg | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/resources/git-hooks/prepare-commit-msg b/resources/git-hooks/prepare-commit-msg index 021a71a5f5..a43bb8206a 100755 --- a/resources/git-hooks/prepare-commit-msg +++ b/resources/git-hooks/prepare-commit-msg @@ -96,7 +96,12 @@ function prepend_scope() { else postfix="" fi - prefix="$TYPE($SCOPE): $EXTRA_WHITESPACE" + + if [ -z "$SCOPE" ]; then + prefix="$TYPE: $EXTRA_WHITESPACE" + else + prefix="$TYPE($SCOPE): $EXTRA_WHITESPACE" + fi # Reuse any existing message text, wrapping it in our conventional commit formatting before # presenting it to the user for any final edits. From b4a809f7d794d0e13ac825bccc9302c38ceb76bc Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 5 Oct 2020 14:00:56 -0400 Subject: [PATCH 16/20] auto: increment master version to 14.0.155 --- HISTORY.md | 10 ++++++++++ VERSION.md | 2 +- .../web/input-processor/package-lock.json | 2 +- common/core/web/input-processor/package.json | 14 ++++++------- .../web/keyboard-processor/package-lock.json | 2 +- .../core/web/keyboard-processor/package.json | 10 +++++----- .../core/web/tools/recorder/package-lock.json | 2 +- common/core/web/tools/recorder/package.json | 10 +++++----- .../tools/sentry-manager/package-lock.json | 2 +- .../web/tools/sentry-manager/package.json | 4 ++-- common/core/web/utils/package-lock.json | 2 +- common/core/web/utils/package.json | 6 +++--- common/models/templates/package-lock.json | 2 +- common/models/templates/package.json | 8 ++++---- common/models/types/package-lock.json | 2 +- common/models/types/package.json | 2 +- common/models/wordbreakers/package-lock.json | 2 +- common/models/wordbreakers/package.json | 4 ++-- common/predictive-text/package-lock.json | 2 +- common/predictive-text/package.json | 14 ++++++------- developer/js/package-lock.json | 2 +- developer/js/package.json | 8 ++++---- lerna.json | 2 +- resources/gosh/package-lock.json | 2 +- resources/gosh/package.json | 2 +- resources/web-environment/package-lock.json | 2 +- resources/web-environment/package.json | 4 ++-- web/package-lock.json | 2 +- web/package.json | 20 +++++++++---------- 29 files changed, 78 insertions(+), 68 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6e68d3174d..e70f220d45 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,15 @@ # Keyman Version History +## 14.0.154 alpha 2020-10-05 + +* fix(windows): Upgrading keyboards with transient profiles (#3637) +* fix(windows): upgrading disabled keyboards (#3638) +* fix(developer): coverity reports for compiler (#3640) +* fix(windows): coverity reports for mcompile (#3641) +* fix(windows): coverity reports for kmtip (#3642) +* fix(windows): coverity reports for keyman32 (#3649) +* chore: exclude parens if no scope in commit msg (#3653) + ## 14.0.153 alpha 2020-10-02 * chore(deps): bump @actions/core from 1.2.2 to 1.2.6 in /resources/build/version (#3646) diff --git a/VERSION.md b/VERSION.md index d02cecea9f..de31f8e7c7 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -14.0.154 \ No newline at end of file +14.0.155 \ No newline at end of file diff --git a/common/core/web/input-processor/package-lock.json b/common/core/web/input-processor/package-lock.json index 39fdfcfd73..c65405e442 100644 --- a/common/core/web/input-processor/package-lock.json +++ b/common/core/web/input-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/input-processor/package.json b/common/core/web/input-processor/package.json index f15eac716e..accb9cd943 100644 --- a/common/core/web/input-processor/package.json +++ b/common/core/web/input-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.154", + "version": "14.0.155", "description": "The core text and prediction processing engine for KeymanWeb", "repository": { "type": "git", @@ -18,7 +18,7 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.154", + "@keymanapp/resources-gosh": "^14.0.155", "chai": "^4.2.0", "mocha": "^5.2.0", "typescript": "^3.8.3" @@ -29,11 +29,11 @@ "test": "gosh ./unit_tests/test.sh" }, "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.154", - "@keymanapp/lexical-model-layer": "^14.0.154", - "@keymanapp/models-types": "^14.0.154", - "@keymanapp/web-environment": "^14.0.154", - "@keymanapp/web-utils": "^14.0.154", + "@keymanapp/keyboard-processor": "^14.0.155", + "@keymanapp/lexical-model-layer": "^14.0.155", + "@keymanapp/models-types": "^14.0.155", + "@keymanapp/web-environment": "^14.0.155", + "@keymanapp/web-utils": "^14.0.155", "@types/node": "^11.9.4", "eventemitter3": "^4.0.0", "ts-node": "^8.0.2" diff --git a/common/core/web/keyboard-processor/package-lock.json b/common/core/web/keyboard-processor/package-lock.json index e70685f0b2..e23e24293b 100644 --- a/common/core/web/keyboard-processor/package-lock.json +++ b/common/core/web/keyboard-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/keyboard-processor/package.json b/common/core/web/keyboard-processor/package.json index 22daeeaae1..b3ba09b60e 100644 --- a/common/core/web/keyboard-processor/package.json +++ b/common/core/web/keyboard-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.154", + "version": "14.0.155", "description": "Core module for Keyman keyboard support in KeymanWeb.", "repository": { "type": "git", @@ -18,7 +18,7 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.154", + "@keymanapp/resources-gosh": "^14.0.155", "chai": "^4.2.0", "mocha": "^5.2.0", "mocha-teamcity-reporter": "^3.0.0", @@ -31,9 +31,9 @@ "mocha": "mocha" }, "dependencies": { - "@keymanapp/models-types": "^14.0.154", - "@keymanapp/web-environment": "^14.0.154", - "@keymanapp/web-utils": "^14.0.154", + "@keymanapp/models-types": "^14.0.155", + "@keymanapp/web-environment": "^14.0.155", + "@keymanapp/web-utils": "^14.0.155", "@types/node": "^11.9.4", "ts-node": "^8.0.2" } diff --git a/common/core/web/tools/recorder/package-lock.json b/common/core/web/tools/recorder/package-lock.json index 31f672ff84..a07d7933a6 100644 --- a/common/core/web/tools/recorder/package-lock.json +++ b/common/core/web/tools/recorder/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/recorder/package.json b/common/core/web/tools/recorder/package.json index fd971b46ef..b74140c295 100644 --- a/common/core/web/tools/recorder/package.json +++ b/common/core/web/tools/recorder/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.154", + "version": "14.0.155", "description": "Core classes used to develop KeymanWeb test cases based on keystrokes", "main": "index.js", "scripts": { @@ -17,10 +17,10 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.154", - "@keymanapp/models-types": "^14.0.154", - "@keymanapp/web-environment": "^14.0.154", - "@keymanapp/web-utils": "^14.0.154" + "@keymanapp/keyboard-processor": "^14.0.155", + "@keymanapp/models-types": "^14.0.155", + "@keymanapp/web-environment": "^14.0.155", + "@keymanapp/web-utils": "^14.0.155" }, "devDependencies": { "typescript": "^3.8.3" diff --git a/common/core/web/tools/sentry-manager/package-lock.json b/common/core/web/tools/sentry-manager/package-lock.json index e5d02ee011..bf7d4a2e74 100644 --- a/common/core/web/tools/sentry-manager/package-lock.json +++ b/common/core/web/tools/sentry-manager/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-sentry-manager", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/sentry-manager/package.json b/common/core/web/tools/sentry-manager/package.json index 4bbf405e52..b8dd31e07f 100644 --- a/common/core/web/tools/sentry-manager/package.json +++ b/common/core/web/tools/sentry-manager/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-sentry-manager", - "version": "14.0.154", + "version": "14.0.155", "description": "Common setup for KeymanWeb's Sentry-based error reporting", "main": "dist/index.js", "scripts": { @@ -20,7 +20,7 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/web-environment": "^14.0.154", + "@keymanapp/web-environment": "^14.0.155", "@sentry/browser": "^5.15.5" } } diff --git a/common/core/web/utils/package-lock.json b/common/core/web/utils/package-lock.json index 530e9edf62..f7584f41e4 100644 --- a/common/core/web/utils/package-lock.json +++ b/common/core/web/utils/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/utils/package.json b/common/core/web/utils/package.json index eecda07c1b..93a60ab77d 100644 --- a/common/core/web/utils/package.json +++ b/common/core/web/utils/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.154", + "version": "14.0.155", "description": "Common utility functions used throughout other Keyman packages", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -20,8 +20,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.154", - "@keymanapp/web-environment": "^14.0.154", + "@keymanapp/resources-gosh": "^14.0.155", + "@keymanapp/web-environment": "^14.0.155", "@types/node": "^14.0.5", "typescript": "^3.8.3" } diff --git a/common/models/templates/package-lock.json b/common/models/templates/package-lock.json index 77bdad0f3c..3bfb56c524 100644 --- a/common/models/templates/package-lock.json +++ b/common/models/templates/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-templates", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/templates/package.json b/common/models/templates/package.json index 11b06206ff..fedfd43d56 100644 --- a/common/models/templates/package.json +++ b/common/models/templates/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-templates", - "version": "14.0.154", + "version": "14.0.155", "description": "Backing model implementations (templates) for Keyman's modelling layer", "keywords": [ "lm", @@ -42,8 +42,8 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/models-types": "^14.0.154", - "@keymanapp/web-utils": "^14.0.154", + "@keymanapp/models-types": "^14.0.155", + "@keymanapp/web-utils": "^14.0.155", "@types/chai": "^4.2.11", "@types/mocha": "^7.0.2", "@types/node": "^14.0.4", @@ -52,6 +52,6 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/models-wordbreakers": "^14.0.154" + "@keymanapp/models-wordbreakers": "^14.0.155" } } diff --git a/common/models/types/package-lock.json b/common/models/types/package-lock.json index debafef43d..389ea4b2d3 100644 --- a/common/models/types/package-lock.json +++ b/common/models/types/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-types", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/types/package.json b/common/models/types/package.json index ea7c318a39..ebb4b761d7 100644 --- a/common/models/types/package.json +++ b/common/models/types/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-types", - "version": "14.0.154", + "version": "14.0.155", "description": "Type definitions in used in the modeling (lexical model/predictive text) component of Keyman.", "types": "./index.d.ts", "scripts": { diff --git a/common/models/wordbreakers/package-lock.json b/common/models/wordbreakers/package-lock.json index 167b2503aa..9239d08f04 100644 --- a/common/models/wordbreakers/package-lock.json +++ b/common/models/wordbreakers/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-wordbreakers", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/wordbreakers/package.json b/common/models/wordbreakers/package.json index f017356102..59492a9516 100644 --- a/common/models/wordbreakers/package.json +++ b/common/models/wordbreakers/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-wordbreakers", - "version": "14.0.154", + "version": "14.0.155", "description": "Word breakers bundled in the modeling layer", "keywords": [ "lexical model", @@ -40,7 +40,7 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/models-types": "^14.0.154", + "@keymanapp/models-types": "^14.0.155", "@types/chai": "^4.2.11", "@types/mocha": "^7.0.2", "chai": "^4.2.0", diff --git a/common/predictive-text/package-lock.json b/common/predictive-text/package-lock.json index 6035ee8a01..830efb9885 100644 --- a/common/predictive-text/package-lock.json +++ b/common/predictive-text/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/predictive-text/package.json b/common/predictive-text/package.json index 257a299a58..bf1eaec4cc 100644 --- a/common/predictive-text/package.json +++ b/common/predictive-text/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.154", + "version": "14.0.155", "description": "Keyman/Predictive Text integration layer", "main": "build/index.js", "scripts": { @@ -21,8 +21,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/models-types": "^14.0.154", - "@keymanapp/resources-gosh": "^14.0.154", + "@keymanapp/models-types": "^14.0.155", + "@keymanapp/resources-gosh": "^14.0.155", "@types/node": "^10.17.21", "chai": "^4.2.0", "karma": "^4.2.0", @@ -46,10 +46,10 @@ "typescript": "^3.8.3" }, "dependencies": { - "@keymanapp/models-templates": "^14.0.154", - "@keymanapp/models-wordbreakers": "^14.0.154", - "@keymanapp/web-environment": "^14.0.154", - "@keymanapp/web-utils": "^14.0.154", + "@keymanapp/models-templates": "^14.0.155", + "@keymanapp/models-wordbreakers": "^14.0.155", + "@keymanapp/web-environment": "^14.0.155", + "@keymanapp/web-utils": "^14.0.155", "es6-shim": "^0.35.5", "string.prototype.codepointat": "^0.2.1", "string.prototype.startswith": "^0.2.0" diff --git a/developer/js/package-lock.json b/developer/js/package-lock.json index 0b36609fa6..84c1f97273 100644 --- a/developer/js/package-lock.json +++ b/developer/js/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-compiler", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/developer/js/package.json b/developer/js/package.json index 0d39273819..56a0bb69e9 100644 --- a/developer/js/package.json +++ b/developer/js/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-compiler", - "version": "14.0.154", + "version": "14.0.155", "description": "Keyman Developer lexical model compiler", "keywords": [ "keyboard", @@ -37,14 +37,14 @@ "node": ">=12.0.0" }, "dependencies": { - "@keymanapp/models-types": "^14.0.154", + "@keymanapp/models-types": "^14.0.155", "commander": "^3.0.0", "typescript": "^3.8.3", "xml2js": "^0.4.19" }, "devDependencies": { - "@keymanapp/models-templates": "^14.0.154", - "@keymanapp/models-wordbreakers": "^14.0.154", + "@keymanapp/models-templates": "^14.0.155", + "@keymanapp/models-wordbreakers": "^14.0.155", "@types/chai": "^4.1.7", "@types/mocha": "^5.2.7", "@types/node": "^10.14.6", diff --git a/lerna.json b/lerna.json index 5473bd4dcc..8057db79ec 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "lerna", "typescript" ], - "version": "14.0.154" + "version": "14.0.155" } diff --git a/resources/gosh/package-lock.json b/resources/gosh/package-lock.json index 884adea3a0..58ab6d723e 100644 --- a/resources/gosh/package-lock.json +++ b/resources/gosh/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1 } diff --git a/resources/gosh/package.json b/resources/gosh/package.json index f374935127..113d6d4c26 100644 --- a/resources/gosh/package.json +++ b/resources/gosh/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.154", + "version": "14.0.155", "description": "Good Ol' Shell", "author": "Marc Durdin (https://github.com/mcdurdin)", "contributors": [ diff --git a/resources/web-environment/package-lock.json b/resources/web-environment/package-lock.json index 72f8bcc422..7144802e22 100644 --- a/resources/web-environment/package-lock.json +++ b/resources/web-environment/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/web-environment", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1 } diff --git a/resources/web-environment/package.json b/resources/web-environment/package.json index f85708fb76..64604cef40 100644 --- a/resources/web-environment/package.json +++ b/resources/web-environment/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-environment", - "version": "14.0.154", + "version": "14.0.155", "description": "A compilation utility for passing select environment variables into our TS builds", "author": "Joshua Horton (https://github.com/jahorton)", "homepage": "https://github.com/keymanapp/keyman", @@ -17,6 +17,6 @@ "url": "https://github.com/keymanapp/keyman/issues" }, "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.154" + "@keymanapp/resources-gosh": "^14.0.155" } } diff --git a/web/package-lock.json b/web/package-lock.json index 0a75da2b9c..e0cec38520 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.154", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/web/package.json b/web/package.json index dbb8898eee..1e91dafbd2 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.154", + "version": "14.0.155", "description": "Facilitates text input in any language.", "repository": { "type": "git", @@ -18,8 +18,8 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "devDependencies": { - "@keymanapp/resources-gosh": "^14.0.154", - "@keymanapp/web-sentry-manager": "^14.0.154", + "@keymanapp/resources-gosh": "^14.0.155", + "@keymanapp/web-sentry-manager": "^14.0.155", "@sentry/cli": "^1.52.3", "chai": "^4.2.0", "google-closure-compiler-java": "^20200224.0.0", @@ -52,13 +52,13 @@ "sentry-cli": "sentry-cli" }, "dependencies": { - "@keymanapp/input-processor": "^14.0.154", - "@keymanapp/keyboard-processor": "^14.0.154", - "@keymanapp/lexical-model-layer": "^14.0.154", - "@keymanapp/models-types": "^14.0.154", - "@keymanapp/recorder-core": "^14.0.154", - "@keymanapp/web-environment": "^14.0.154", - "@keymanapp/web-utils": "^14.0.154", + "@keymanapp/input-processor": "^14.0.155", + "@keymanapp/keyboard-processor": "^14.0.155", + "@keymanapp/lexical-model-layer": "^14.0.155", + "@keymanapp/models-types": "^14.0.155", + "@keymanapp/recorder-core": "^14.0.155", + "@keymanapp/web-environment": "^14.0.155", + "@keymanapp/web-utils": "^14.0.155", "@types/node": "^11.9.4", "es6-shim": "^0.35.5", "eventemitter3": "^4.0.0", From 07067227bdf25cd673c29c75c98a33f777a4eafd Mon Sep 17 00:00:00 2001 From: jahorton Date: Tue, 6 Oct 2020 09:06:00 +0700 Subject: [PATCH 17/20] refactor(common/models): centralizes quotation logic, defs --- common/models/templates/src/index.ts | 1 + common/models/templates/src/quote-behavior.ts | 46 +++++++++++++++++++ .../worker/model-compositor.ts | 21 +++------ 3 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 common/models/templates/src/quote-behavior.ts diff --git a/common/models/templates/src/index.ts b/common/models/templates/src/index.ts index 5d63fe73a5..a20b43f602 100644 --- a/common/models/templates/src/index.ts +++ b/common/models/templates/src/index.ts @@ -1,4 +1,5 @@ /// +/// // Add all namespaces defined here to the global scope: if (typeof module != 'undefined' && typeof module.exports != 'undefined') { diff --git a/common/models/templates/src/quote-behavior.ts b/common/models/templates/src/quote-behavior.ts new file mode 100644 index 0000000000..d71dd688dc --- /dev/null +++ b/common/models/templates/src/quote-behavior.ts @@ -0,0 +1,46 @@ +namespace models { + export enum QuoteBehavior { + noQuotes = "no-quotes", + useQuotes = "use-quotes", + default = "default-quotes" + } + + // For an "enum/namespace merge". See https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-namespaces-with-classes + export namespace QuoteBehavior { + /** + * Applies the specified quote behavior to the provided `Transform`, mutating it as appropriate. + * @param transform The Transform to be mutated + * @param punctuation The active `LexicalModelPunctuation` settings + * @param defaultTo The default quote behavior to use (in case the current value is `.default`) + */ + export function apply(behavior: QuoteBehavior, text: string, punctuation: LexicalModelPunctuation, defaultTo: QuoteBehavior): string { + if(defaultTo == QuoteBehavior.default || !defaultTo) { + throw "Specified quote behavior may be ambiguous - default behavior not specified (may not be .default)"; + } + + if(behavior == QuoteBehavior.default) { + behavior = defaultTo; + } + + switch(behavior) { + case QuoteBehavior.noQuotes: + return text; + case QuoteBehavior.useQuotes: + let {open, close} = punctuation.quotesForKeepSuggestion; + + // TODO: Is this the right thing to do under RTL? + // We need an extra pass over this section to validate it. + if(punctuation.isRTL) { + let temp = close; + close = open; + open = temp; + } + + // This part's simple enough, at least. + return open + text + close; + default: + throw "Unsupported quote behavior state detected; implementation missing!"; + } + } + } +} \ No newline at end of file diff --git a/common/predictive-text/worker/model-compositor.ts b/common/predictive-text/worker/model-compositor.ts index 05b20bb745..ea2ab3c50e 100644 --- a/common/predictive-text/worker/model-compositor.ts +++ b/common/predictive-text/worker/model-compositor.ts @@ -221,7 +221,7 @@ class ModelCompositor { } keepOption = models.transformToSuggestion(keepTransform, prediction.p); - keepOption = this.toAnnotatedKeepSuggestion(keepOption, true); + keepOption = this.toAnnotatedKeepSuggestion(keepOption, models.QuoteBehavior.noQuotes); } else { let existingSuggestion = suggestionDistribMap[displayText]; if(existingSuggestion) { @@ -283,25 +283,18 @@ class ModelCompositor { return suggestions; } - private toAnnotatedKeepSuggestion(suggestion: Suggestion & {p?: number}, noQuotes: boolean = false): Suggestion & {p?: number} { - let { open, close } = this.punctuation.quotesForKeepSuggestion; - - if(noQuotes) { - open = ''; - close = ''; - } else if(this.punctuation.isRTL) { - let temp = close; - close = open; - open = temp; - } + private toAnnotatedKeepSuggestion(suggestion: Suggestion & {p?: number}, + quoteBehavior: models.QuoteBehavior = models.QuoteBehavior.default): Suggestion & {p?: number} { + // A method-internal 'import' of the enum. + let QuoteBehavior = models.QuoteBehavior; return { transform: suggestion.transform, transformId: suggestion.transformId, - displayAs: open + suggestion.displayAs + close, + displayAs: QuoteBehavior.apply(quoteBehavior, suggestion.displayAs, this.punctuation, QuoteBehavior.useQuotes), tag: 'keep', p: suggestion.p - } + }; } /** From 95e5ce47bf772dcb4a7cf8c73014e6267683c0a9 Mon Sep 17 00:00:00 2001 From: jahorton Date: Tue, 6 Oct 2020 10:08:16 +0700 Subject: [PATCH 18/20] feat(common/models): quote behavior unit tests --- .../templates/test/test-quote-behavior.js | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 common/models/templates/test/test-quote-behavior.js diff --git a/common/models/templates/test/test-quote-behavior.js b/common/models/templates/test/test-quote-behavior.js new file mode 100644 index 0000000000..80964b7a7f --- /dev/null +++ b/common/models/templates/test/test-quote-behavior.js @@ -0,0 +1,150 @@ +/* + * Unit tests for the priority queue. + */ + +var assert = require('chai').assert; +var QuoteBehavior = require('../').models.QuoteBehavior; + +describe('Quote behaviors', function() { + describe('Script directionality', function() { + it('(default)', function() { + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: " " + } + + var plainQuotedHello; + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes); + assert.equal(plainQuotedHello, "“hello”"); + }); + + it('LTR', function() { + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: " ", + isRTL: false + } + + var plainQuotedHello; + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes); + assert.equal(plainQuotedHello, "“hello”"); + }); + + it.skip('RTL', function() { + // TODO: + }); + }); + + describe('Application', function() { + it('.useQuotes', function() { + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: " " + } + + var plainQuotedHello; + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes); + assert.equal(plainQuotedHello, "“hello”"); + + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.noQuotes); + assert.equal(plainQuotedHello, "“hello”"); + + let angleQuotePunctuation = { + quotesForKeepSuggestion: { open: `«`, close: `»`}, + insertAfterWord: " " + } + + var angleQuotedHello; + angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes); + assert.equal(angleQuotedHello, "«hello»"); + + angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes); + assert.equal(angleQuotedHello, "«hello»"); + }); + + it('.noQuotes', function() { + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: " " + } + + var plainQuotedHello; + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes); + assert.equal(plainQuotedHello, "hello"); + + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.noQuotes); + assert.equal(plainQuotedHello, "hello"); + + let angleQuotePunctuation = { + quotesForKeepSuggestion: { open: `«`, close: `»`}, + insertAfterWord: " " + } + + var angleQuotedHello; + angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes); + assert.equal(angleQuotedHello, "hello"); + + angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes); + assert.equal(angleQuotedHello, "hello"); + }); + + it('.default -> .useQuotes', function() { + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: " " + } + + var plainQuotedHello; + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.useQuotes); + assert.equal(plainQuotedHello, "“hello”"); + + let angleQuotePunctuation = { + quotesForKeepSuggestion: { open: `«`, close: `»`}, + insertAfterWord: " " + } + + var angleQuotedHello; + angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes); + assert.equal(angleQuotedHello, "«hello»"); + }); + + it('.default -> .noQuotes', function() { + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: " " + } + + var plainQuotedHello; + plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.noQuotes); + assert.equal(plainQuotedHello, "hello"); + + let angleQuotePunctuation = { + quotesForKeepSuggestion: { open: `«`, close: `»`}, + insertAfterWord: " " + } + + var angleQuotedHello; + angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes); + assert.equal(angleQuotedHello, "hello"); + }); + + it('Error case: .default as fall-back behavior', function() { + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: " " + } + + assert.throws(function() { + QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.default); + }); + + assert.throws(function() { + QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.default); + }); + + assert.throws(function() { + QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.default); + }); + }); + }); +}); \ No newline at end of file From 8d5b70cd773a32bb5bb9bfa42df613efd5a04763 Mon Sep 17 00:00:00 2001 From: jahorton Date: Tue, 6 Oct 2020 10:39:32 +0700 Subject: [PATCH 19/20] feat(common/models): transformToSuggestion unit test --- common/models/templates/src/common.ts | 10 ++- common/models/templates/test/test-common.js | 70 +++++++++++++++++++ .../templates/test/test-quote-behavior.js | 2 +- 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 common/models/templates/test/test-common.js diff --git a/common/models/templates/src/common.ts b/common/models/templates/src/common.ts index fe3b285c7c..73d360a2e7 100644 --- a/common/models/templates/src/common.ts +++ b/common/models/templates/src/common.ts @@ -71,11 +71,15 @@ namespace models { export function transformToSuggestion(transform: Transform): Suggestion; export function transformToSuggestion(transform: Transform, p: number): Suggestion & {p: number}; export function transformToSuggestion(transform: Transform, p?: number): Suggestion & {p?: number} { - return { + let suggestion: Suggestion & {p?: number} = { transform: transform, transformId: transform.id, - displayAs: transform.insert, - p: p + displayAs: transform.insert }; + + if(p === 0 || p) { + suggestion.p = p; + } + return suggestion; } } diff --git a/common/models/templates/test/test-common.js b/common/models/templates/test/test-common.js new file mode 100644 index 0000000000..61892ad985 --- /dev/null +++ b/common/models/templates/test/test-common.js @@ -0,0 +1,70 @@ +/* + * Unit tests for common utility functions/methods. + */ + +var assert = require('chai').assert; +var models = require('../').models; + +describe('Common utility functions', function() { + // TODO: unit tests for other common utility functions + + describe('transformToSuggestion', function() { + it('p: undefined', function() { + let suggestion = { + transform: { + insert: 'hello', + deleteLeft: 0, + id: 0 + }, + transformId: 0, + displayAs: 'hello' + }; + + assert.deepEqual(models.transformToSuggestion(suggestion.transform), suggestion); + }); + + it('p: 0', function() { + let suggestion = { + transform: { + insert: 'hello', + deleteLeft: 0, + id: 0 + }, + transformId: 0, + displayAs: 'hello', + p: 0 + }; + + assert.deepEqual(models.transformToSuggestion(suggestion.transform, 0), suggestion); + }); + + it('p > 0', function() { + let suggestion = { + transform: { + insert: 'hello', + deleteLeft: 0, + id: 0 + }, + transformId: 0, + displayAs: 'hello', + p: 0.5 + }; + + assert.deepEqual(models.transformToSuggestion(suggestion.transform, 0.5), suggestion); + }); + + it('properly handles the transformId', function() { + let suggestion = { + transform: { + insert: 'hello', + deleteLeft: 0, + id: 3 + }, + transformId: 3, // Ensures there isn't a separate ID seed in use. + displayAs: 'hello' + }; + + assert.deepEqual(models.transformToSuggestion(suggestion.transform), suggestion); + }); + }); +}); diff --git a/common/models/templates/test/test-quote-behavior.js b/common/models/templates/test/test-quote-behavior.js index 80964b7a7f..339cf0af9d 100644 --- a/common/models/templates/test/test-quote-behavior.js +++ b/common/models/templates/test/test-quote-behavior.js @@ -1,5 +1,5 @@ /* - * Unit tests for the priority queue. + * Unit tests for quote behaviors. */ var assert = require('chai').assert; From 5becd0973230d5b08cb10b8b708fc3f065a2f7a3 Mon Sep 17 00:00:00 2001 From: jahorton Date: Tue, 6 Oct 2020 11:06:03 +0700 Subject: [PATCH 20/20] feat(common/models): suggestion annotation unit test --- .../headless/worker-model-compositor.js | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/common/predictive-text/unit_tests/headless/worker-model-compositor.js b/common/predictive-text/unit_tests/headless/worker-model-compositor.js index bdd60699ca..1ba4ba0497 100644 --- a/common/predictive-text/unit_tests/headless/worker-model-compositor.js +++ b/common/predictive-text/unit_tests/headless/worker-model-compositor.js @@ -2,6 +2,8 @@ * Integration tests for the model compositor with the trie model. */ +const { models } = require('../../build/intermediate'); + var assert = require('chai').assert; var TrieModel = require('../../build/intermediate').models.TrieModel; var ModelCompositor = require('../../build/intermediate').ModelCompositor; @@ -66,4 +68,70 @@ describe('ModelCompositor', function() { // 'the' should be the intended the result here. assert.isAbove(theSuggestion.p, thrSuggestion.p); }); + + // The nomenclature's a minor sneak-peek from child PRs. + describe('toAnnotatedSuggestion', function() { + let baseSuggestion = { + transform: { + insert: 'hello', + deleteLeft: 0, + id: 0 + }, + transformId: 0, + displayAs: 'hello' + }; + + let englishPunctuation = { + quotesForKeepSuggestion: { open: `“`, close: `”`}, + insertAfterWord: ' ' + }; + + let angledPunctuation = { + quotesForKeepSuggestion: { open: `«`, close: `»`}, + insertAfterWord: " " + } + + describe("'keep'", function() { + let annotationTest = function(punctuation, displayText, quoteStyle) { + let options = { + punctuation: punctuation + }; + + let model = new models.DummyModel(options); + let compositor = new ModelCompositor(model); + + var keep; + if(quoteStyle) { + keep = compositor.toAnnotatedKeepSuggestion(baseSuggestion, quoteStyle); + } else { + keep = compositor.toAnnotatedKeepSuggestion(baseSuggestion); + } + + // Make sure we didn't accidentally leak any mutations to the parameter. + assert.notDeepEqual(keep, baseSuggestion); + + assert.equal(keep.displayAs, displayText); + assert.equal(keep.tag, 'keep'); + } + + it('quoteBehavior: (.default)', function() { + annotationTest(englishPunctuation, "“hello”"); + annotationTest(angledPunctuation, "«hello»"); + }); + + it('quoteBehavior: .useQuotes', function() { + annotationTest(englishPunctuation, "“hello”", models.QuoteBehavior.useQuotes); + annotationTest(angledPunctuation, "«hello»", models.QuoteBehavior.useQuotes); + }); + + it('quoteBehavior: .noQuotes', function() { + annotationTest(englishPunctuation, "hello", models.QuoteBehavior.noQuotes); + annotationTest(angledPunctuation, "hello", models.QuoteBehavior.noQuotes); + }); + + it.skip('RTL test', function() { + // TODO: + }); + }); + }); });