Skip to content

Commit

Permalink
Merge pull request #10062 from keymanapp/feat/developer/warn-on-vk-in…
Browse files Browse the repository at this point in the history
…-output

feat(developer): warn on usage of virtual keys in rule output
  • Loading branch information
mcdurdin authored Nov 24, 2023
2 parents ff6a9fc + e983818 commit a47137b
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions developer/src/common/include/kmn_compiler_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@

#define CHINT_UnreachableRule 0x000010AE

#define CWARN_VirtualKeyInOutput 0x000020AF

#define CERR_BufferOverflow 0x000080C0
#define CERR_Break 0x000080C1

Expand Down
2 changes: 2 additions & 0 deletions developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ export class KmnCompilerMessages {

static HINT_UnreachableRule = SevHint | 0x0AE;

static WARN_VirtualKeyInOutput = SevWarn | 0x0AF;

static FATAL_BufferOverflow = SevFatal | 0x0C0;
static FATAL_Break = SevFatal | 0x0C1;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
store(&NAME) 'WARN_VirtualKeyInOutput'
store(&VERSION) '9.0'

begin Unicode > use(main)

group(main) using keys

c WARN_VirtualKeyInOutput
+ 'a' > [K_BKQUOTE]
7 changes: 7 additions & 0 deletions developer/src/kmc-kmn/test/test-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,11 @@ describe('CompilerMessages', function () {
assert.equal(callbacks.messages[0].message, "Statement 'return' is not currently supported in output for web and touch targets");
});

// WARN_VirtualKeyInOutput

it('should generate WARN_VirtualKeyInOutput if a virtual key is found in the output part of a rule', async function() {
await testForMessage(this, ['invalid-keyboards', 'warn_virtual_key_in_output.kmn'], KmnCompilerMessages.WARN_VirtualKeyInOutput);
assert.equal(callbacks.messages[0].message, "Virtual keys are not supported in output");
});

});
1 change: 1 addition & 0 deletions developer/src/kmcmplib/src/CompMsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ const struct CompilerError CompilerErrors[] = {
{ CWARN_NulNotFirstStatementInContext , "nul must be the first statement in the context"},
{ CWARN_IfShouldBeAtStartOfContext , "if, platform and baselayout should be at start of context (after nul, if present)"},
{ CWARN_KeyShouldIncludeNCaps , "Other rules which reference this key include CAPS or NCAPS modifiers, so this rule must include NCAPS modifier to avoid inconsistent matches"},
{ CWARN_VirtualKeyInOutput , "Virtual keys are not supported in output"},

{ 0, nullptr }
};
Expand Down
22 changes: 22 additions & 0 deletions developer/src/kmcmplib/src/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,7 @@ KMX_BOOL CheckContextStatementPositions(PKMX_WCHAR context) {

return TRUE;
}

/**
* Checks if a use() statement is followed by other content in the output of a rule
*/
Expand All @@ -1348,6 +1349,22 @@ KMX_DWORD CheckUseStatementsInOutput(PKMX_WCHAR output) {
return CERR_None;
}

/**
* Warn if output has virtual keys in it, which is not supported by Core at all,
* but was unofficially supported, but never worked properly, in Keyman for
* Windows for many years
*/
KMX_DWORD CheckVirtualKeysInOutput(PKMX_WCHAR output) {
PKMX_WCHAR p;
for (p = output; *p; p = incxstr(p)) {
if (*p == UC_SENTINEL && *(p + 1) == CODE_EXTENDED) {
AddWarning(CWARN_VirtualKeyInOutput);
break;
}
}
return CERR_None;
}

/**
* Adds implicit `context` to start of output of rules for readonly groups
*/
Expand Down Expand Up @@ -1472,6 +1489,11 @@ KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnico
return msg; // I4867
}

// Warn if virtual keys are used in the output, as they are unsupported by Core
if ((msg = CheckVirtualKeysInOutput(pklOut)) != CERR_None) {
return msg;
}

if (gp->fReadOnly) {
// Ensure no output is made from the rule, and that
// use() statements meet required readonly semantics
Expand Down

0 comments on commit a47137b

Please sign in to comment.