mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-07 17:36:00 +00:00
Merge branch 'master' of https://github.com/keymanapp/keyman into refactor/developer/6026-kmcompx-compiler-cross-platform-part-2-NEW_VERSION # Conflicts: # common/core/desktop/src/kmx/kmx_context.h # common/core/desktop/src/kmx/kmx_processor.cpp # common/windows/cpp/include/keymanversion.h # common/windows/cpp/include/kkmnkbd/Compfile.h # common/windows/cpp/include/kmtip_guids.h # common/windows/cpp/src/kmtip_guids.cpp # core/src/kmx/kmx_conversion.cpp # core/src/kmx/kmx_conversion.h # core/src/kmx/kmx_file.cpp # core/src/kmx/kmx_processevent.cpp # core/src/kmx/kmx_processor.hpp # core/src/kmx/kmx_xstring.cpp # developer/js/.gitignore # developer/js/package-lock.json # developer/js/tests/tsconfig.json # developer/src/kmcmpdll/CasedKeys.cpp # developer/src/kmcmpdll/CheckFilenameConsistency.cpp # developer/src/kmcmpdll/CheckFilenameConsistency.h # developer/src/kmcmpdll/CheckForDuplicates.cpp # developer/src/kmcmpdll/CheckForDuplicates.h # developer/src/kmcmpdll/CheckNCapsConsistency.cpp # developer/src/kmcmpdll/CheckNCapsConsistency.h # developer/src/kmcmpdll/Compiler.cpp # developer/src/kmcmpdll/DeprecationChecks.cpp # developer/src/kmcmpdll/NamedCodeConstants.cpp # developer/src/kmcmpdll/UnreachableRules.cpp # developer/src/kmcmpdll/UnreachableRules.h # developer/src/kmcmpdll/compfile.h # developer/src/kmcmpdll/kcframe/kcframe.cpp # developer/src/kmcmpdll/kcframe/kcframe.vcxproj # developer/src/kmcmpdll/kcframe/kcframe.vcxproj.filters # developer/src/kmcmpdll/kmcmpdll.vcxproj # developer/src/kmcmpdll/kmcmpdll.vcxproj.filters # developer/src/kmcmpdll/version.rc # developer/src/kmcmpdll/versioning.cpp # developer/src/kmlmc/bundle.sh # developer/src/kmlmc/tests/test-join-word-breaker.ts # developer/src/kmlmc/tests/test-override-script-defaults.ts # developer/src/server/tsconfig.json # windows/src/developer/kmcmpdll/Makefile # windows/src/developer/kmcmpdll/vkeys.h # windows/src/engine/keyman32/keymanengine.h # windows/src/global/inc/Vkeys.h # windows/src/global/inc/rc4.h # windows/src/global/vc/rc4.cpp
103 lines
3.5 KiB
C++
103 lines
3.5 KiB
C++
|
|
#include "../../../../developer/kmcompx/include/pch.h" // _S2 #include "pch.h"
|
|
#include "CheckNCapsConsistency.h"
|
|
//#include "../../../../developer/kmcompx/include/compfile.h" // _S2 #include <compfile.h>
|
|
//#include "../../../../developer/kmcompx/include/compiler.h" // _S2 #include <compiler.h>
|
|
//#include <comperr.h> // double?
|
|
|
|
//#include "../../../../developer/kmcompx/include/kmcmpdll.h" // _S2 #include <kmcmpdll.h>
|
|
#include "CharToKeyConversion.h"
|
|
|
|
#include <windows.h> // added _S2 needed?
|
|
|
|
/**
|
|
* If any rule uses CAPS or NCAPS for a given key, then every rule that
|
|
* uses that key must also use CAPS or NCAPS, as otherwise the results are
|
|
* inconsistent. For example, if Caps Lock is on, then [K_F] may still be
|
|
* matched:
|
|
*
|
|
* + [K_F] > 'foo'
|
|
* + [CAPS K_F] > 'bar'
|
|
*
|
|
* Because of the way that KeymanWeb compiles rules, this may even apply when
|
|
* we have a key rule that would otherwise be ignored due to context. In the
|
|
* following example, [Caps Lock] + [y] would result in no output (or default
|
|
* output) rather than 'bar', because the preceding rule would capture the
|
|
* Y key, ignoring Caps Lock, meaning that the subsequent rule would never
|
|
* even get tested. (Note that this was introduced in the KeymanWeb compiler
|
|
* fix for extremely long if/else ladders in Keyman 12 in #1561, and this is
|
|
* technically slightly inconsistent with Keyman Core, although in my analysis
|
|
* only in this already ambiguous situation.
|
|
*
|
|
* 'x' + [K_Y] > 'foo'
|
|
* [CAPS K_Y] > 'bar'
|
|
*
|
|
* Given all this, we'll warn any time we find a key that has inconsistent use
|
|
* of CAPS/NCAPS in its rules.
|
|
*
|
|
* @param fk Keyboard to check
|
|
*/
|
|
|
|
bool CheckNCapsConsistency(PFILE_KEYBOARD fk) {
|
|
struct CapsUsage {
|
|
int ncaps_line, caps_line, neither_line;
|
|
};
|
|
|
|
// 256 virtual key codes + sizeof the virtual key dictionary is max key code possible
|
|
const int nkeys = 256 + fk->cxVKDictionary;
|
|
const int oldCurrentLine = currentLine;
|
|
auto caps_ncaps_usage = new CapsUsage [nkeys];
|
|
|
|
memset(caps_ncaps_usage, 0, nkeys * sizeof(CapsUsage));
|
|
|
|
PFILE_GROUP gp;
|
|
KMX_DWORD gn;
|
|
for (gn = 0, gp = fk->dpGroupArray; gn < fk->cxGroupArray; gn++, gp++) {
|
|
if (!gp->fUsingKeys) {
|
|
continue;
|
|
}
|
|
|
|
PFILE_KEY kp;
|
|
KMX_DWORD kn;
|
|
for (kn = 0, kp = gp->dpKeyArray; kn < gp->cxKeyArray; kn++, kp++) {
|
|
KMX_UINT key;
|
|
KMX_UINT shift;
|
|
if (kp->ShiftFlags & ISVIRTUALKEY) {
|
|
if (kp->Key >= nkeys) {
|
|
assert(false);
|
|
continue;
|
|
}
|
|
key = kp->Key;
|
|
shift = kp->ShiftFlags;
|
|
}
|
|
else if (!MapUSCharToVK(kp->Key, &key, &shift)) {
|
|
// Not a valid key
|
|
continue;
|
|
}
|
|
|
|
if (shift & NOTCAPITALFLAG) {
|
|
if (!caps_ncaps_usage[key].ncaps_line) caps_ncaps_usage[key].ncaps_line = (kp->Line == 0 ? 1 : kp->Line);
|
|
}
|
|
else if (shift & CAPITALFLAG) {
|
|
if (!caps_ncaps_usage[key].caps_line) caps_ncaps_usage[key].caps_line = (kp->Line == 0 ? 1 : kp->Line);
|
|
}
|
|
else {
|
|
if (!caps_ncaps_usage[key].neither_line) caps_ncaps_usage[key].neither_line = (kp->Line == 0 ? 1 : kp->Line);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < nkeys; i++) {
|
|
if (caps_ncaps_usage[i].neither_line && (caps_ncaps_usage[i].caps_line || caps_ncaps_usage[i].ncaps_line)) {
|
|
// We set the current line to one needing work: the developer should add the NCAPS flag
|
|
currentLine = caps_ncaps_usage[i].neither_line;
|
|
AddWarning(CWARN_KeyShouldIncludeNCaps);
|
|
}
|
|
}
|
|
|
|
delete[] caps_ncaps_usage;
|
|
|
|
currentLine = oldCurrentLine;
|
|
|
|
return TRUE;
|
|
}
|