From 421ce40f3c9a418916f4ccd298649ba2fc716bd0 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 6 May 2024 16:03:06 +0100 Subject: [PATCH 01/53] chore(developer): add IsValidKeyBoardVersion test --- developer/src/kmcmplib/src/meson.build | 4 ++++ developer/src/kmcmplib/subprojects/.gitignore | 1 + developer/src/kmcmplib/subprojects/gtest.wrap | 16 ++++++++++++++ .../kmcmplib/tests/gtest-compiler-test.cpp | 21 +++++++++++++++++++ developer/src/kmcmplib/tests/meson.build | 13 ++++++++++++ 5 files changed, 55 insertions(+) create mode 100644 developer/src/kmcmplib/subprojects/gtest.wrap create mode 100644 developer/src/kmcmplib/tests/gtest-compiler-test.cpp diff --git a/developer/src/kmcmplib/src/meson.build b/developer/src/kmcmplib/src/meson.build index e3e4efcd48..af2c776335 100644 --- a/developer/src/kmcmplib/src/meson.build +++ b/developer/src/kmcmplib/src/meson.build @@ -116,3 +116,7 @@ if cpp_compiler.get_id() == 'emscripten' endif endif + +gtest = subproject('gtest') +gtest_dep = gtest.get_variable('gtest_main_dep') +gmock_dep = gtest.get_variable('gmock_dep') diff --git a/developer/src/kmcmplib/subprojects/.gitignore b/developer/src/kmcmplib/subprojects/.gitignore index 99479aa952..37346d9045 100644 --- a/developer/src/kmcmplib/subprojects/.gitignore +++ b/developer/src/kmcmplib/subprojects/.gitignore @@ -2,3 +2,4 @@ /*.zip /*.tgz /packagecache +/googletest-1.14.0 diff --git a/developer/src/kmcmplib/subprojects/gtest.wrap b/developer/src/kmcmplib/subprojects/gtest.wrap new file mode 100644 index 0000000000..adb8a9a6d9 --- /dev/null +++ b/developer/src/kmcmplib/subprojects/gtest.wrap @@ -0,0 +1,16 @@ +[wrap-file] +directory = googletest-1.14.0 +source_url = https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz +source_filename = gtest-1.14.0.tar.gz +source_hash = 8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7 +patch_filename = gtest_1.14.0-2_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.14.0-2/get_patch +patch_hash = 4ec7f767364386a99f7b2d61678287a73ad6ba0f9998be43b51794c464a63732 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/gtest_1.14.0-2/gtest-1.14.0.tar.gz +wrapdb_version = 1.14.0-2 + +[provide] +gtest = gtest_dep +gtest_main = gtest_main_dep +gmock = gmock_dep +gmock_main = gmock_main_dep diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp new file mode 100644 index 0000000000..0a98242a18 --- /dev/null +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -0,0 +1,21 @@ +#include +#include "..\..\..\..\common\include\km_types.h" + +KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); + +TEST(Compiler, IsValidKeyboardVersion_test) { + KMX_WCHAR ver_empty[] = { 0x0000 }; + EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_empty)); + KMX_WCHAR ver_valid[] = { 0x0031, 0x002E, 0x0031, 0x0000 }; // 1.1 + EXPECT_EQ(TRUE, IsValidKeyboardVersion(ver_valid)); + KMX_WCHAR ver_extra_zero[] = { 0x0031, 0x002E, 0x0030, 0x0000 }; // 1.0, should fail but doesn't + EXPECT_EQ(TRUE, IsValidKeyboardVersion(ver_extra_zero)); + KMX_WCHAR ver_trailing_point[] = { 0x0031, 0x002E, 0x0000 }; // 1. + EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_trailing_point)); + KMX_WCHAR ver_three_level[] = { 0x0031, 0x002E, 0x0032, 0x002E, 0x0033, 0x0000 }; // 1.2.3, should fail but doesn't + EXPECT_EQ(TRUE, IsValidKeyboardVersion(ver_three_level)); + KMX_WCHAR ver_letter[] = { 0x0061, 0x0000 }; // a + EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_letter)); + KMX_WCHAR ver_trailing_letter[] = { 0x0031, 0x002E, 0x0061, 0x0000 }; // 1.a + EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_trailing_letter)); +} diff --git a/developer/src/kmcmplib/tests/meson.build b/developer/src/kmcmplib/tests/meson.build index ae023d70b0..a712a502c6 100644 --- a/developer/src/kmcmplib/tests/meson.build +++ b/developer/src/kmcmplib/tests/meson.build @@ -152,3 +152,16 @@ usetapitest = executable('uset-api-test', 'uset-api-test.cpp', ) test('uset-api-test', usetapitest) + +# Google Test + +gtestcompilertest = executable('gtest-compiler-test', 'gtest-compiler-test.cpp', + cpp_args: defns + flags, + include_directories: inc, + name_suffix: name_suffix, + link_args: links + tests_links, + objects: lib.extract_all_objects(), + dependencies: [ icuuc_dep, gtest_dep, gmock_dep ], + ) + +test('gtest-compiler-test', gtestcompilertest) From fa8d3a4a65598f915f825d343ac09ee3be467950 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 6 May 2024 16:14:45 +0100 Subject: [PATCH 02/53] chore(developer): change IsValidKeyboardVersion to use more specific expects --- .../src/kmcmplib/tests/gtest-compiler-test.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 0a98242a18..a13e070e3f 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -5,17 +5,17 @@ KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); TEST(Compiler, IsValidKeyboardVersion_test) { KMX_WCHAR ver_empty[] = { 0x0000 }; - EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_empty)); + EXPECT_FALSE(IsValidKeyboardVersion(ver_empty)); KMX_WCHAR ver_valid[] = { 0x0031, 0x002E, 0x0031, 0x0000 }; // 1.1 - EXPECT_EQ(TRUE, IsValidKeyboardVersion(ver_valid)); + EXPECT_TRUE(IsValidKeyboardVersion(ver_valid)); KMX_WCHAR ver_extra_zero[] = { 0x0031, 0x002E, 0x0030, 0x0000 }; // 1.0, should fail but doesn't - EXPECT_EQ(TRUE, IsValidKeyboardVersion(ver_extra_zero)); + EXPECT_TRUE(IsValidKeyboardVersion(ver_extra_zero)); KMX_WCHAR ver_trailing_point[] = { 0x0031, 0x002E, 0x0000 }; // 1. - EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_trailing_point)); + EXPECT_FALSE(IsValidKeyboardVersion(ver_trailing_point)); KMX_WCHAR ver_three_level[] = { 0x0031, 0x002E, 0x0032, 0x002E, 0x0033, 0x0000 }; // 1.2.3, should fail but doesn't - EXPECT_EQ(TRUE, IsValidKeyboardVersion(ver_three_level)); + EXPECT_TRUE(IsValidKeyboardVersion(ver_three_level)); KMX_WCHAR ver_letter[] = { 0x0061, 0x0000 }; // a - EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_letter)); + EXPECT_FALSE(IsValidKeyboardVersion(ver_letter)); KMX_WCHAR ver_trailing_letter[] = { 0x0031, 0x002E, 0x0061, 0x0000 }; // 1.a - EXPECT_EQ(FALSE, IsValidKeyboardVersion(ver_trailing_letter)); + EXPECT_FALSE(IsValidKeyboardVersion(ver_trailing_letter)); } From aad39d5e609d37c8c693095bd6a5a58135fa5067 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 7 May 2024 13:21:17 +0100 Subject: [PATCH 03/53] chore(developer): add global thread compilation argument for emscripten to overcome wasm build problem --- developer/src/kmcmplib/src/meson.build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/developer/src/kmcmplib/src/meson.build b/developer/src/kmcmplib/src/meson.build index af2c776335..61b909a75e 100644 --- a/developer/src/kmcmplib/src/meson.build +++ b/developer/src/kmcmplib/src/meson.build @@ -54,6 +54,10 @@ if cpp_compiler.get_id() == 'emscripten' # emscripten < 3.1.44 does not include `wasmExports` links += ['-sEXPORTED_RUNTIME_METHODS=[\'UTF8ToString\']'] endif + + # For Google Test + add_global_arguments('-pthread', language: [ 'cpp', 'c' ] ) + endif icu = subproject('icu-for-uset', default_options: [ 'default_library=static', 'cpp_std=c++17', 'warning_level=0', 'werror=false']) From 46efc978335b1b24dcf867b80ebe1bbe0407efa0 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 May 2024 10:52:15 +0100 Subject: [PATCH 04/53] chore(developer): add fixture class and symbolic constants for KMX_WCHARs --- .../kmcmplib/tests/gtest-compiler-test.cpp | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index a13e070e3f..d8e8a6fec2 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -3,19 +3,30 @@ KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); -TEST(Compiler, IsValidKeyboardVersion_test) { - KMX_WCHAR ver_empty[] = { 0x0000 }; +class CompilerTest : public testing::Test { + protected: + const KMX_WCHAR WCHAR_NULL = 0x0000; + const KMX_WCHAR FULL_STOP = 0x002E; + const KMX_WCHAR DIGIT_ZERO = 0x0030; + const KMX_WCHAR DIGIT_ONE = 0x0031; + const KMX_WCHAR DIGIT_TWO = 0x0032; + const KMX_WCHAR DIGIT_THREE = 0x0033; + const KMX_WCHAR LATIN_SMALL_LETTER_A = 0x0061; +}; + +TEST_F(CompilerTest, IsValidKeyboardVersion_test) { + KMX_WCHAR ver_empty[] = { WCHAR_NULL }; EXPECT_FALSE(IsValidKeyboardVersion(ver_empty)); - KMX_WCHAR ver_valid[] = { 0x0031, 0x002E, 0x0031, 0x0000 }; // 1.1 + KMX_WCHAR ver_valid[] = { DIGIT_ONE, FULL_STOP, DIGIT_ONE, WCHAR_NULL }; // 1.1 EXPECT_TRUE(IsValidKeyboardVersion(ver_valid)); - KMX_WCHAR ver_extra_zero[] = { 0x0031, 0x002E, 0x0030, 0x0000 }; // 1.0, should fail but doesn't + KMX_WCHAR ver_extra_zero[] = { DIGIT_ONE, FULL_STOP, DIGIT_ZERO, WCHAR_NULL }; // 1.0, should fail but doesn't EXPECT_TRUE(IsValidKeyboardVersion(ver_extra_zero)); - KMX_WCHAR ver_trailing_point[] = { 0x0031, 0x002E, 0x0000 }; // 1. + KMX_WCHAR ver_trailing_point[] = { DIGIT_ONE, FULL_STOP, WCHAR_NULL }; // 1. EXPECT_FALSE(IsValidKeyboardVersion(ver_trailing_point)); - KMX_WCHAR ver_three_level[] = { 0x0031, 0x002E, 0x0032, 0x002E, 0x0033, 0x0000 }; // 1.2.3, should fail but doesn't + KMX_WCHAR ver_three_level[] = { DIGIT_ONE, FULL_STOP, DIGIT_TWO, FULL_STOP, DIGIT_THREE, WCHAR_NULL }; // 1.2.3, should fail but doesn't EXPECT_TRUE(IsValidKeyboardVersion(ver_three_level)); - KMX_WCHAR ver_letter[] = { 0x0061, 0x0000 }; // a + KMX_WCHAR ver_letter[] = { LATIN_SMALL_LETTER_A, WCHAR_NULL }; // a EXPECT_FALSE(IsValidKeyboardVersion(ver_letter)); - KMX_WCHAR ver_trailing_letter[] = { 0x0031, 0x002E, 0x0061, 0x0000 }; // 1.a + KMX_WCHAR ver_trailing_letter[] = { DIGIT_ONE, FULL_STOP, LATIN_SMALL_LETTER_A, WCHAR_NULL }; // 1.a EXPECT_FALSE(IsValidKeyboardVersion(ver_trailing_letter)); } From 2f528c26b08ca917fbd0c759c0d079c344616b12 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 May 2024 11:44:50 +0100 Subject: [PATCH 05/53] chore(developer): add strtowstr test --- .../kmcmplib/tests/gtest-compiler-test.cpp | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index d8e8a6fec2..655e8f752e 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -1,6 +1,9 @@ #include +#include "..\include\kmcompx.h" +#include "..\src\kmx_u16.h" #include "..\..\..\..\common\include\km_types.h" +PKMX_WCHAR strtowstr(PKMX_STR in); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); class CompilerTest : public testing::Test { @@ -12,6 +15,26 @@ class CompilerTest : public testing::Test { const KMX_WCHAR DIGIT_TWO = 0x0032; const KMX_WCHAR DIGIT_THREE = 0x0033; const KMX_WCHAR LATIN_SMALL_LETTER_A = 0x0061; + const KMX_WCHAR LATIN_SMALL_LETTER_E = 0x0065; + const KMX_WCHAR LATIN_SMALL_LETTER_H = 0x0068; + const KMX_WCHAR LATIN_SMALL_LETTER_L = 0x006C; + const KMX_WCHAR LATIN_SMALL_LETTER_O = 0x006F; +}; + +TEST_F(CompilerTest, strtowstr_test) { + const KMX_CHAR in_hello[] = "hello"; + const KMX_WCHAR out_hello[] = { + LATIN_SMALL_LETTER_H, + LATIN_SMALL_LETTER_E, + LATIN_SMALL_LETTER_L, + LATIN_SMALL_LETTER_L, + LATIN_SMALL_LETTER_O, + WCHAR_NULL + }; + EXPECT_EQ(0, u16cmp(out_hello, strtowstr((PKMX_STR)in_hello))); + const KMX_CHAR in_empty[] = ""; + const KMX_WCHAR out_empty[] = { WCHAR_NULL }; + EXPECT_EQ(0, u16cmp(out_empty, strtowstr((PKMX_STR)in_empty))); }; TEST_F(CompilerTest, IsValidKeyboardVersion_test) { @@ -29,4 +52,4 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { EXPECT_FALSE(IsValidKeyboardVersion(ver_letter)); KMX_WCHAR ver_trailing_letter[] = { DIGIT_ONE, FULL_STOP, LATIN_SMALL_LETTER_A, WCHAR_NULL }; // 1.a EXPECT_FALSE(IsValidKeyboardVersion(ver_trailing_letter)); -} +}; From ebfb3c57398f314c9ea7f827db05af0d012a86b4 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 May 2024 12:06:32 +0100 Subject: [PATCH 06/53] chore(developer): add wstrtostr test --- .../src/kmcmplib/tests/gtest-compiler-test.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 655e8f752e..d09c09b184 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -4,6 +4,7 @@ #include "..\..\..\..\common\include\km_types.h" PKMX_WCHAR strtowstr(PKMX_STR in); +PKMX_STR wstrtostr(PKMX_WCHAR in); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); class CompilerTest : public testing::Test { @@ -37,6 +38,22 @@ TEST_F(CompilerTest, strtowstr_test) { EXPECT_EQ(0, u16cmp(out_empty, strtowstr((PKMX_STR)in_empty))); }; +TEST_F(CompilerTest, wstrtostr_test) { + const KMX_WCHAR in_hello[] = { + LATIN_SMALL_LETTER_H, + LATIN_SMALL_LETTER_E, + LATIN_SMALL_LETTER_L, + LATIN_SMALL_LETTER_L, + LATIN_SMALL_LETTER_O, + WCHAR_NULL + }; + const KMX_CHAR out_hello[] = "hello"; + EXPECT_EQ(0, strcmp(out_hello, wstrtostr((PKMX_WCHAR)in_hello))); + const KMX_WCHAR in_empty[] = { WCHAR_NULL }; + const KMX_CHAR out_empty[] = ""; + EXPECT_EQ(0, strcmp(out_empty, wstrtostr((PKMX_WCHAR)in_empty))); +}; + TEST_F(CompilerTest, IsValidKeyboardVersion_test) { KMX_WCHAR ver_empty[] = { WCHAR_NULL }; EXPECT_FALSE(IsValidKeyboardVersion(ver_empty)); From 3b23164b37443ff89d8dc3a99d3a94e2c124cf20 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 May 2024 12:52:41 +0100 Subject: [PATCH 07/53] chore(developer): switch to use of u"xx" strings --- .../kmcmplib/tests/gtest-compiler-test.cpp | 75 ++++++------------- 1 file changed, 24 insertions(+), 51 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index d09c09b184..1b673c4d4b 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -9,64 +9,37 @@ KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); class CompilerTest : public testing::Test { protected: - const KMX_WCHAR WCHAR_NULL = 0x0000; - const KMX_WCHAR FULL_STOP = 0x002E; - const KMX_WCHAR DIGIT_ZERO = 0x0030; - const KMX_WCHAR DIGIT_ONE = 0x0031; - const KMX_WCHAR DIGIT_TWO = 0x0032; - const KMX_WCHAR DIGIT_THREE = 0x0033; - const KMX_WCHAR LATIN_SMALL_LETTER_A = 0x0061; - const KMX_WCHAR LATIN_SMALL_LETTER_E = 0x0065; - const KMX_WCHAR LATIN_SMALL_LETTER_H = 0x0068; - const KMX_WCHAR LATIN_SMALL_LETTER_L = 0x006C; - const KMX_WCHAR LATIN_SMALL_LETTER_O = 0x006F; + CompilerTest() {} + ~CompilerTest() override {} + void SetUp() override {} + void TearDown() override {} }; TEST_F(CompilerTest, strtowstr_test) { - const KMX_CHAR in_hello[] = "hello"; - const KMX_WCHAR out_hello[] = { - LATIN_SMALL_LETTER_H, - LATIN_SMALL_LETTER_E, - LATIN_SMALL_LETTER_L, - LATIN_SMALL_LETTER_L, - LATIN_SMALL_LETTER_O, - WCHAR_NULL - }; - EXPECT_EQ(0, u16cmp(out_hello, strtowstr((PKMX_STR)in_hello))); - const KMX_CHAR in_empty[] = ""; - const KMX_WCHAR out_empty[] = { WCHAR_NULL }; - EXPECT_EQ(0, u16cmp(out_empty, strtowstr((PKMX_STR)in_empty))); + EXPECT_EQ(0, u16cmp(u"hello", strtowstr((PKMX_STR)"hello"))); + EXPECT_EQ(0, u16cmp(u"", strtowstr((PKMX_STR)""))); }; TEST_F(CompilerTest, wstrtostr_test) { - const KMX_WCHAR in_hello[] = { - LATIN_SMALL_LETTER_H, - LATIN_SMALL_LETTER_E, - LATIN_SMALL_LETTER_L, - LATIN_SMALL_LETTER_L, - LATIN_SMALL_LETTER_O, - WCHAR_NULL - }; - const KMX_CHAR out_hello[] = "hello"; - EXPECT_EQ(0, strcmp(out_hello, wstrtostr((PKMX_WCHAR)in_hello))); - const KMX_WCHAR in_empty[] = { WCHAR_NULL }; - const KMX_CHAR out_empty[] = ""; - EXPECT_EQ(0, strcmp(out_empty, wstrtostr((PKMX_WCHAR)in_empty))); + EXPECT_EQ(0, strcmp("hello", wstrtostr((PKMX_WCHAR)u"hello"))); + EXPECT_EQ(0, strcmp("", wstrtostr((PKMX_WCHAR)u""))); }; +// KMX_BOOL kmcmp::AddCompileWarning(PKMX_CHAR buf) +// KMX_BOOL AddCompileError(KMX_DWORD msg) +// KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) + +TEST_F(CompilerTest, ValidateMatchNomatchOutput_test) { +} + TEST_F(CompilerTest, IsValidKeyboardVersion_test) { - KMX_WCHAR ver_empty[] = { WCHAR_NULL }; - EXPECT_FALSE(IsValidKeyboardVersion(ver_empty)); - KMX_WCHAR ver_valid[] = { DIGIT_ONE, FULL_STOP, DIGIT_ONE, WCHAR_NULL }; // 1.1 - EXPECT_TRUE(IsValidKeyboardVersion(ver_valid)); - KMX_WCHAR ver_extra_zero[] = { DIGIT_ONE, FULL_STOP, DIGIT_ZERO, WCHAR_NULL }; // 1.0, should fail but doesn't - EXPECT_TRUE(IsValidKeyboardVersion(ver_extra_zero)); - KMX_WCHAR ver_trailing_point[] = { DIGIT_ONE, FULL_STOP, WCHAR_NULL }; // 1. - EXPECT_FALSE(IsValidKeyboardVersion(ver_trailing_point)); - KMX_WCHAR ver_three_level[] = { DIGIT_ONE, FULL_STOP, DIGIT_TWO, FULL_STOP, DIGIT_THREE, WCHAR_NULL }; // 1.2.3, should fail but doesn't - EXPECT_TRUE(IsValidKeyboardVersion(ver_three_level)); - KMX_WCHAR ver_letter[] = { LATIN_SMALL_LETTER_A, WCHAR_NULL }; // a - EXPECT_FALSE(IsValidKeyboardVersion(ver_letter)); - KMX_WCHAR ver_trailing_letter[] = { DIGIT_ONE, FULL_STOP, LATIN_SMALL_LETTER_A, WCHAR_NULL }; // 1.a - EXPECT_FALSE(IsValidKeyboardVersion(ver_trailing_letter)); + EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"")); + EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u" ")); + EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"\t")); + EXPECT_TRUE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.1")); + EXPECT_TRUE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.0")); + EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.")); + EXPECT_TRUE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.2.3")); + EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"a")); + EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.a")); }; From 90b12c2a3895549fe12d20baa65a087fcc7424fc Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 May 2024 12:56:09 +0100 Subject: [PATCH 08/53] chore(developer): add improved comment in IsValidKeyboardVersion --- developer/src/kmcmplib/src/Compiler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 75409f5141..b5b9bccf6c 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -1208,7 +1208,11 @@ int GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store) { } KMX_BOOL IsValidKeyboardVersion(KMX_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 */ + /** + version format: /^\d+(\.\d+)*$/ + e.g. 9.0.3, 1.0, 1.2.3.4, 6.2.1.4.6.4, 11.22.3 are all ok; + empty string is not permitted; whitespace is not permitted + */ do { if (!iswdigit(*dpString)) { From 4cae4310f0fbf073b5d07fd709dacfbce32d8c81 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 9 May 2024 13:43:34 +0100 Subject: [PATCH 09/53] chore(developer): add ValidateMatchNomatchOutput test --- .../src/kmcmplib/tests/gtest-compiler-test.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 1b673c4d4b..730b11dc3d 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -2,9 +2,12 @@ #include "..\include\kmcompx.h" #include "..\src\kmx_u16.h" #include "..\..\..\..\common\include\km_types.h" +#include "..\..\..\..\common\include\kmx_file.h" +#include "..\..\..\..\common\include\kmn_compiler_errors.h" PKMX_WCHAR strtowstr(PKMX_STR in); PKMX_STR wstrtostr(PKMX_WCHAR in); +KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); class CompilerTest : public testing::Test { @@ -30,7 +33,17 @@ TEST_F(CompilerTest, wstrtostr_test) { // KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) TEST_F(CompilerTest, ValidateMatchNomatchOutput_test) { -} + EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput(NULL)); + EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput((PKMX_WCHAR)u"")); + const KMX_WCHAR context[] = { 'a', 'b', 'c', UC_SENTINEL, CODE_CONTEXT, 'd', 'e', 'f' }; + EXPECT_EQ(CERR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)context)); + const KMX_WCHAR contextex[] = { 'a', 'b', 'c', UC_SENTINEL, CODE_CONTEXTEX, 'd', 'e', 'f' }; + EXPECT_EQ(CERR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)contextex)); + const KMX_WCHAR index[] = { 'a', 'b', 'c', UC_SENTINEL, CODE_INDEX, 'd', 'e', 'f' }; + EXPECT_EQ(CERR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)index)); + const KMX_WCHAR sentinel[] = { 'a', 'b', 'c', UC_SENTINEL, 'd', 'e', 'f' }; + EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput((PKMX_WCHAR)sentinel)); +}; TEST_F(CompilerTest, IsValidKeyboardVersion_test) { EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"")); From 34b61cd49c23953905a9cd46af862f33577ae751 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 May 2024 10:32:59 +0100 Subject: [PATCH 10/53] chore(developer): add additional test case to IsValidKeyboardVersion test --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 730b11dc3d..dcee750510 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -49,6 +49,7 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"")); EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u" ")); EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"\t")); + EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u" 1.1")); EXPECT_TRUE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.1")); EXPECT_TRUE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.0")); EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.")); From 330070fe910eb12edb75a77d67325d0942c7349a Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 May 2024 11:29:55 +0100 Subject: [PATCH 11/53] chore(developer): add list of functions needing test (as comments) --- .../kmcmplib/tests/gtest-compiler-test.cpp | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index dcee750510..7898c187b9 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -45,6 +45,18 @@ TEST_F(CompilerTest, ValidateMatchNomatchOutput_test) { EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput((PKMX_WCHAR)sentinel)); }; +// KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) +// KMX_DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +// int kmcmp::cmpkeys(const void *key, const void *elem) +// KMX_DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) +// KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +// bool resizeStoreArray(PFILE_KEYBOARD fk) +// bool resizeKeyArray(PFILE_GROUP gp, int increment) +// KMX_DWORD AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, KMX_DWORD *dwStoreID) +// KMX_DWORD AddDebugStore(PFILE_KEYBOARD fk, KMX_WCHAR const * str) +// KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp) +// int GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store) + TEST_F(CompilerTest, IsValidKeyboardVersion_test) { EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"")); EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u" ")); @@ -57,3 +69,58 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"a")); EXPECT_FALSE(IsValidKeyboardVersion((KMX_WCHAR *)u"1.a")); }; + +// KMX_DWORD kmcmp::AddCompilerVersionStore(PFILE_KEYBOARD fk) +// KMX_DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PKMX_WCHAR context, PKMX_WCHAR output, PKMX_WCHAR key) +// KMX_BOOL CheckContextStatementPositions(PKMX_WCHAR context) +// KMX_DWORD CheckUseStatementsInOutput(PKMX_WCHAR output) +// KMX_DWORD CheckVirtualKeysInOutput(PKMX_WCHAR output) +// KMX_DWORD InjectContextToReadonlyOutput(PKMX_WCHAR pklOut) +// KMX_DWORD CheckOutputIsReadonly(const PFILE_KEYBOARD fk, const PKMX_WCHAR output) +// KMX_DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode) +// KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode, PKMX_WCHAR pklIn, PKMX_WCHAR pklKey, PKMX_WCHAR pklOut) +// KMX_DWORD ExpandKp_ReplaceIndex(PFILE_KEYBOARD fk, PFILE_KEY k, KMX_DWORD keyIndex, int nAnyIndex) +// KMX_DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, KMX_DWORD storeIndex) +// PKMX_WCHAR GetDelimitedString(PKMX_WCHAR *p, KMX_WCHAR const * Delimiters, KMX_WORD Flags) +// LinePrefixType GetLinePrefixType(PKMX_WCHAR *p) +// int LineTokenType(PKMX_WCHAR *str) +// KMX_BOOL StrValidChrs(PKMX_WCHAR q, KMX_WCHAR const * chrs) +// KMX_DWORD GetXString(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, +// PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int /*isVKey*/, int isUnicode +// ) +// KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, +// PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int isUnicode +// ) +// KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// KMX_DWORD process_platform(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// KMX_DWORD process_reset(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx, int max) +// KMX_DWORD process_set_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// KMX_DWORD process_save(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +// int xatoi(PKMX_WCHAR *p) +// int GetGroupNum(PFILE_KEYBOARD fk, PKMX_WCHAR p) +// KMX_DWORD ProcessEthnologueStore(PKMX_WCHAR p) +// KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) +// void SetChecksum(PKMX_BYTE buf, PKMX_DWORD CheckSum, KMX_DWORD sz) +// KMX_BOOL kmcmp::CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall) +// KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataSize) +// KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess) +// KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode) +// void safe_wcsncpy(PKMX_WCHAR out, PKMX_WCHAR in, int cbMax) +// KMX_BOOL IsSameToken(PKMX_WCHAR *p, KMX_WCHAR const * token) +// static bool endsWith(const std::string& str, const std::string& suffix) +// KMX_DWORD ImportBitmapFile(PFILE_KEYBOARD fk, PKMX_WCHAR szName, PKMX_DWORD FileSize, PKMX_BYTE *Buf) +// int atoiW(PKMX_WCHAR p) +// KMX_DWORD kmcmp::CheckUTF16(int n) +// KMX_DWORD kmcmp::UTF32ToUTF16(int n, int *n1, int *n2) +// KMX_DWORD BuildVKDictionary(PFILE_KEYBOARD fk) +// int GetVKCode(PFILE_KEYBOARD fk, PKMX_WCHAR p) +// int GetDeadKey(PFILE_KEYBOARD fk, PKMX_WCHAR p) +// void kmcmp::RecordDeadkeyNames(PFILE_KEYBOARD fk) +// KMX_BOOL kmcmp::IsValidCallStore(PFILE_STORE fs) +// bool hasPreamble(std::u16string result) +// bool UTF16TempFromUTF8(KMX_BYTE* infile, int sz, KMX_BYTE** tempfile, int *sz16) +// PFILE_STORE FindSystemStore(PFILE_KEYBOARD fk, KMX_DWORD dwSystemID) From 35f401780f890de13766dd84c0c85d27830adbb0 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 May 2024 11:50:23 +0100 Subject: [PATCH 12/53] chore(developer): add hasPreamble test --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 7898c187b9..3904b8996c 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -9,6 +9,7 @@ PKMX_WCHAR strtowstr(PKMX_STR in); PKMX_STR wstrtostr(PKMX_WCHAR in); KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); +bool hasPreamble(std::u16string result); class CompilerTest : public testing::Test { protected: @@ -121,6 +122,12 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { // int GetDeadKey(PFILE_KEYBOARD fk, PKMX_WCHAR p) // void kmcmp::RecordDeadkeyNames(PFILE_KEYBOARD fk) // KMX_BOOL kmcmp::IsValidCallStore(PFILE_STORE fs) -// bool hasPreamble(std::u16string result) + +TEST_F(CompilerTest, hasPreamble_test) { + EXPECT_FALSE(hasPreamble(u"")); + EXPECT_FALSE(hasPreamble(u"\uFEFE")); // not \uFEFF + EXPECT_TRUE(hasPreamble(u"\uFEFF")); +} + // bool UTF16TempFromUTF8(KMX_BYTE* infile, int sz, KMX_BYTE** tempfile, int *sz16) // PFILE_STORE FindSystemStore(PFILE_KEYBOARD fk, KMX_DWORD dwSystemID) From bd4aeffcb7df95e2fde1011989f57d3ad71f8b47 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 May 2024 12:20:32 +0100 Subject: [PATCH 13/53] chore(developer): add CompMsg GetCompilerErrorString test --- .../src/kmcmplib/tests/gtest-compmsg-test.cpp | 19 +++++++++++++++++++ developer/src/kmcmplib/tests/meson.build | 11 +++++++++++ 2 files changed, 30 insertions(+) create mode 100644 developer/src/kmcmplib/tests/gtest-compmsg-test.cpp diff --git a/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp b/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp new file mode 100644 index 0000000000..aa1f2d8c8f --- /dev/null +++ b/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp @@ -0,0 +1,19 @@ +#include +#include "..\..\..\..\common\include\km_types.h" +#include "..\..\..\..\common\include\kmn_compiler_errors.h" + +KMX_CHAR *GetCompilerErrorString(KMX_DWORD code); + +class CompMsgTest : public testing::Test { + protected: + CompMsgTest() {} + ~CompMsgTest() override {} + void SetUp() override {} + void TearDown() override {} +}; + +TEST_F(CompMsgTest, GetCompilerErrorString) { + EXPECT_EQ(nullptr, GetCompilerErrorString(CERR_None)); + EXPECT_EQ(nullptr, GetCompilerErrorString(0x00004FFF)); // top of range ERROR + EXPECT_EQ("Invalid 'layout' command", GetCompilerErrorString(CERR_InvalidLayoutLine)); +}; \ No newline at end of file diff --git a/developer/src/kmcmplib/tests/meson.build b/developer/src/kmcmplib/tests/meson.build index a712a502c6..fe3b19c4b4 100644 --- a/developer/src/kmcmplib/tests/meson.build +++ b/developer/src/kmcmplib/tests/meson.build @@ -165,3 +165,14 @@ gtestcompilertest = executable('gtest-compiler-test', 'gtest-compiler-test.cpp', ) test('gtest-compiler-test', gtestcompilertest) + +gtestcompmsgtest = executable('gtest-compmsg-test', 'gtest-compmsg-test.cpp', + cpp_args: defns + flags, + include_directories: inc, + name_suffix: name_suffix, + link_args: links + tests_links, + objects: lib.extract_all_objects(), + dependencies: [ icuuc_dep, gtest_dep, gmock_dep ], + ) + +test('gtest-compmsg-test', gtestcompmsgtest) From e8ecb67c66b679cb35c2265adaeddddc9f7add94 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 May 2024 12:29:41 +0100 Subject: [PATCH 14/53] chore(developer): add extra test case to hasPreamble test --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 3904b8996c..b608ca1c06 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -127,6 +127,7 @@ TEST_F(CompilerTest, hasPreamble_test) { EXPECT_FALSE(hasPreamble(u"")); EXPECT_FALSE(hasPreamble(u"\uFEFE")); // not \uFEFF EXPECT_TRUE(hasPreamble(u"\uFEFF")); + EXPECT_FALSE(hasPreamble(u"a\uFEFF")); } // bool UTF16TempFromUTF8(KMX_BYTE* infile, int sz, KMX_BYTE** tempfile, int *sz16) From 651bd92043836ff6e63592911ba6f4f7e380d37b Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 13 May 2024 16:44:49 +0100 Subject: [PATCH 15/53] chore(developer): add initial AddCompilerError test --- .../kmcmplib/tests/gtest-compiler-test.cpp | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index b608ca1c06..18dda795d3 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -1,22 +1,48 @@ #include #include "..\include\kmcompx.h" +#include "..\include\kmcmplibapi.h" #include "..\src\kmx_u16.h" +#include "..\src\compfile.h" #include "..\..\..\..\common\include\km_types.h" #include "..\..\..\..\common\include\kmx_file.h" #include "..\..\..\..\common\include\kmn_compiler_errors.h" PKMX_WCHAR strtowstr(PKMX_STR in); PKMX_STR wstrtostr(PKMX_WCHAR in); +KMX_BOOL AddCompileError(KMX_DWORD msg); KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); bool hasPreamble(std::u16string result); +extern kmcmp_CompilerMessageProc msgproc; + +#define COMPILE_ERROR_MAX_LEN (SZMAX_ERRORTEXT + 1 + 280) +KMX_CHAR szText_stub[COMPILE_ERROR_MAX_LEN]; + +int msgproc_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { + strcpy(szText_stub, szText); + return 1; +} + +namespace kmcmp { + extern int nErrors; + extern int ErrChr; +} + +#define ERR_EXTRA_LIB_LEN 256 +extern char ErrExtraLIB[ERR_EXTRA_LIB_LEN]; + class CompilerTest : public testing::Test { protected: CompilerTest() {} ~CompilerTest() override {} void SetUp() override {} - void TearDown() override {} + void TearDown() override { + msgproc = NULL; + szText_stub[0] = '\0'; + kmcmp::nErrors = 0; + kmcmp::ErrChr = 0; + } }; TEST_F(CompilerTest, strtowstr_test) { @@ -30,7 +56,31 @@ TEST_F(CompilerTest, wstrtostr_test) { }; // KMX_BOOL kmcmp::AddCompileWarning(PKMX_CHAR buf) -// KMX_BOOL AddCompileError(KMX_DWORD msg) + +TEST_F(CompilerTest, AddCompileError_test) { + msgproc = msgproc_stub; + kmcmp::ErrChr = 0; + + // CERR_FATAL + EXPECT_EQ(0, kmcmp::nErrors); + EXPECT_EQ(CERR_FATAL, CERR_CannotCreateTempfile & CERR_FATAL); + EXPECT_TRUE(AddCompileError(CERR_CannotCreateTempfile)); + EXPECT_EQ(0, strcmp("Cannot create temp file", szText_stub)); + EXPECT_EQ(1, kmcmp::nErrors); + + // CERR_ERROR + EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); + EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); + EXPECT_EQ(0, strcmp("Invalid 'layout' command", szText_stub)); + EXPECT_EQ(2, kmcmp::nErrors); + + // Unknown + EXPECT_EQ(CERR_ERROR, 0x00004FFF & CERR_ERROR); + EXPECT_FALSE(AddCompileError(0x00004FFF)); // top of range ERROR + EXPECT_EQ(0, strcmp("Unknown error 4fff", szText_stub)); + EXPECT_EQ(3, kmcmp::nErrors); +}; + // KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) TEST_F(CompilerTest, ValidateMatchNomatchOutput_test) { From 8e47082d20067452ce4e175d0d3cd174e817750e Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 14 May 2024 10:58:33 +0100 Subject: [PATCH 16/53] chore(developer): add extra test cases to AddCompileError test --- .../kmcmplib/tests/gtest-compiler-test.cpp | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 18dda795d3..b9846d2ed4 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -24,6 +24,11 @@ int msgproc_stub(int line, uint32_t dwMsgCode, const char* szText, void* context return 1; } +int msgproc_false_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { + strcpy(szText_stub, szText); + return 0; +} + namespace kmcmp { extern int nErrors; extern int ErrChr; @@ -42,6 +47,7 @@ class CompilerTest : public testing::Test { szText_stub[0] = '\0'; kmcmp::nErrors = 0; kmcmp::ErrChr = 0; + ErrExtraLIB[0] = '\0'; } }; @@ -60,6 +66,7 @@ TEST_F(CompilerTest, wstrtostr_test) { TEST_F(CompilerTest, AddCompileError_test) { msgproc = msgproc_stub; kmcmp::ErrChr = 0; + ErrExtraLIB[0] = '\0'; // CERR_FATAL EXPECT_EQ(0, kmcmp::nErrors); @@ -79,6 +86,29 @@ TEST_F(CompilerTest, AddCompileError_test) { EXPECT_FALSE(AddCompileError(0x00004FFF)); // top of range ERROR EXPECT_EQ(0, strcmp("Unknown error 4fff", szText_stub)); EXPECT_EQ(3, kmcmp::nErrors); + + // ErrChr + kmcmp::ErrChr = 42; + EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); + EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); + EXPECT_EQ(0, strcmp("Invalid 'layout' command character offset: 42", szText_stub)); + kmcmp::ErrChr = 0; + EXPECT_EQ(4, kmcmp::nErrors); + + // ErrExtraLIB + strcpy(ErrExtraLIB, " extra lib"); + EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); + EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); + EXPECT_EQ(0, strcmp("Invalid 'layout' command extra lib", szText_stub)); + ErrExtraLIB[0] = '\0'; + EXPECT_EQ(5, kmcmp::nErrors); + + // msgproc returns FALSE + msgproc = msgproc_false_stub; + EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); + EXPECT_TRUE(AddCompileError(CERR_InvalidLayoutLine)); + EXPECT_EQ(0, strcmp("Invalid 'layout' command", szText_stub)); + EXPECT_EQ(6, kmcmp::nErrors); }; // KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) From 451731f5b1000ac79ee246f8ef4d3b70228d6241 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 16 May 2024 10:50:23 +0100 Subject: [PATCH 17/53] chore(developer): move the msgproc stubbing into the test class --- .../kmcmplib/tests/gtest-compiler-test.cpp | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index b9846d2ed4..b380493648 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -16,19 +16,6 @@ bool hasPreamble(std::u16string result); extern kmcmp_CompilerMessageProc msgproc; -#define COMPILE_ERROR_MAX_LEN (SZMAX_ERRORTEXT + 1 + 280) -KMX_CHAR szText_stub[COMPILE_ERROR_MAX_LEN]; - -int msgproc_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { - strcpy(szText_stub, szText); - return 1; -} - -int msgproc_false_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { - strcpy(szText_stub, szText); - return 0; -} - namespace kmcmp { extern int nErrors; extern int ErrChr; @@ -49,8 +36,24 @@ class CompilerTest : public testing::Test { kmcmp::ErrChr = 0; ErrExtraLIB[0] = '\0'; } + + public: + static KMX_CHAR szText_stub[]; + + static int msgproc_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { + strcpy(szText_stub, szText); + return 1; + }; + + static int msgproc_false_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { + strcpy(szText_stub, szText); + return 0; + }; }; +#define COMPILE_ERROR_MAX_LEN (SZMAX_ERRORTEXT + 1 + 280) +KMX_CHAR CompilerTest::szText_stub[COMPILE_ERROR_MAX_LEN]; + TEST_F(CompilerTest, strtowstr_test) { EXPECT_EQ(0, u16cmp(u"hello", strtowstr((PKMX_STR)"hello"))); EXPECT_EQ(0, u16cmp(u"", strtowstr((PKMX_STR)""))); From 95b9986709952180a262ade3883e2acb9eb3b54f Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 16 May 2024 11:11:44 +0100 Subject: [PATCH 18/53] chore(developer): use GetCompilerErrorString to fetch error messages for tests --- .../kmcmplib/tests/gtest-compiler-test.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index b380493648..178a84a1a4 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -3,6 +3,7 @@ #include "..\include\kmcmplibapi.h" #include "..\src\kmx_u16.h" #include "..\src\compfile.h" +#include "..\src\CompMsg.h" #include "..\..\..\..\common\include\km_types.h" #include "..\..\..\..\common\include\kmx_file.h" #include "..\..\..\..\common\include\kmn_compiler_errors.h" @@ -70,18 +71,21 @@ TEST_F(CompilerTest, AddCompileError_test) { msgproc = msgproc_stub; kmcmp::ErrChr = 0; ErrExtraLIB[0] = '\0'; + KMX_CHAR expected[COMPILE_ERROR_MAX_LEN]; // CERR_FATAL EXPECT_EQ(0, kmcmp::nErrors); EXPECT_EQ(CERR_FATAL, CERR_CannotCreateTempfile & CERR_FATAL); EXPECT_TRUE(AddCompileError(CERR_CannotCreateTempfile)); - EXPECT_EQ(0, strcmp("Cannot create temp file", szText_stub)); + strcpy(expected, GetCompilerErrorString(CERR_CannotCreateTempfile)); + EXPECT_EQ(0, strcmp(expected, szText_stub)); EXPECT_EQ(1, kmcmp::nErrors); // CERR_ERROR EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp("Invalid 'layout' command", szText_stub)); + strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); + EXPECT_EQ(0, strcmp(expected, szText_stub)); EXPECT_EQ(2, kmcmp::nErrors); // Unknown @@ -94,7 +98,9 @@ TEST_F(CompilerTest, AddCompileError_test) { kmcmp::ErrChr = 42; EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp("Invalid 'layout' command character offset: 42", szText_stub)); + strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); + strcat(expected, " character offset: 42"); + EXPECT_EQ(0, strcmp(expected, szText_stub)); kmcmp::ErrChr = 0; EXPECT_EQ(4, kmcmp::nErrors); @@ -102,7 +108,9 @@ TEST_F(CompilerTest, AddCompileError_test) { strcpy(ErrExtraLIB, " extra lib"); EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp("Invalid 'layout' command extra lib", szText_stub)); + strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); + strcat(expected, " extra lib"); + EXPECT_EQ(0, strcmp(expected, szText_stub)); ErrExtraLIB[0] = '\0'; EXPECT_EQ(5, kmcmp::nErrors); @@ -110,7 +118,8 @@ TEST_F(CompilerTest, AddCompileError_test) { msgproc = msgproc_false_stub; EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_TRUE(AddCompileError(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp("Invalid 'layout' command", szText_stub)); + strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); + EXPECT_EQ(0, strcmp(expected, szText_stub)); EXPECT_EQ(6, kmcmp::nErrors); }; From db257139fb7108306190ab69ba54d29fa01d4c10 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 16 May 2024 11:39:56 +0100 Subject: [PATCH 19/53] chore(developer): refactor AddCompileError test to use const local variables --- .../kmcmplib/tests/gtest-compiler-test.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 178a84a1a4..80e941e5a5 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -89,27 +89,29 @@ TEST_F(CompilerTest, AddCompileError_test) { EXPECT_EQ(2, kmcmp::nErrors); // Unknown - EXPECT_EQ(CERR_ERROR, 0x00004FFF & CERR_ERROR); - EXPECT_FALSE(AddCompileError(0x00004FFF)); // top of range ERROR - EXPECT_EQ(0, strcmp("Unknown error 4fff", szText_stub)); + const KMX_DWORD UNKNOWN_ERROR = 0x00004FFF; // top of range ERROR + EXPECT_EQ(CERR_ERROR, UNKNOWN_ERROR & CERR_ERROR); + EXPECT_FALSE(AddCompileError(UNKNOWN_ERROR)); + sprintf(expected, "Unknown error %x", UNKNOWN_ERROR); + EXPECT_EQ(0, strcmp(expected, szText_stub)); EXPECT_EQ(3, kmcmp::nErrors); // ErrChr - kmcmp::ErrChr = 42; + const int ERROR_CHAR_INDEX = 42; + kmcmp::ErrChr = ERROR_CHAR_INDEX ; EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); - strcat(expected, " character offset: 42"); + sprintf(expected, "%s character offset: %d", GetCompilerErrorString(CERR_InvalidLayoutLine), ERROR_CHAR_INDEX); EXPECT_EQ(0, strcmp(expected, szText_stub)); kmcmp::ErrChr = 0; EXPECT_EQ(4, kmcmp::nErrors); // ErrExtraLIB - strcpy(ErrExtraLIB, " extra lib"); + const char *const EXTRA_LIB_TEXT = " extra lib"; + strcpy(ErrExtraLIB, EXTRA_LIB_TEXT); EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); - strcat(expected, " extra lib"); + sprintf(expected, "%s%s", GetCompilerErrorString(CERR_InvalidLayoutLine), EXTRA_LIB_TEXT); EXPECT_EQ(0, strcmp(expected, szText_stub)); ErrExtraLIB[0] = '\0'; EXPECT_EQ(5, kmcmp::nErrors); From a099c86ad89c8c37f160b3c670a8d4679a307da3 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 16 May 2024 11:49:43 +0100 Subject: [PATCH 20/53] chore(developer): remove unnecessary use of local variable in three AddCompileError test cases --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 80e941e5a5..a76fa0ea20 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -77,15 +77,13 @@ TEST_F(CompilerTest, AddCompileError_test) { EXPECT_EQ(0, kmcmp::nErrors); EXPECT_EQ(CERR_FATAL, CERR_CannotCreateTempfile & CERR_FATAL); EXPECT_TRUE(AddCompileError(CERR_CannotCreateTempfile)); - strcpy(expected, GetCompilerErrorString(CERR_CannotCreateTempfile)); - EXPECT_EQ(0, strcmp(expected, szText_stub)); + EXPECT_EQ(0, strcmp(GetCompilerErrorString(CERR_CannotCreateTempfile), szText_stub)); EXPECT_EQ(1, kmcmp::nErrors); // CERR_ERROR EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp(expected, szText_stub)); + EXPECT_EQ(0, strcmp(GetCompilerErrorString(CERR_InvalidLayoutLine), szText_stub)); EXPECT_EQ(2, kmcmp::nErrors); // Unknown @@ -120,8 +118,7 @@ TEST_F(CompilerTest, AddCompileError_test) { msgproc = msgproc_false_stub; EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); EXPECT_TRUE(AddCompileError(CERR_InvalidLayoutLine)); - strcpy(expected, GetCompilerErrorString(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp(expected, szText_stub)); + EXPECT_EQ(0, strcmp(GetCompilerErrorString(CERR_InvalidLayoutLine), szText_stub)); EXPECT_EQ(6, kmcmp::nErrors); }; From 5ea3f6ec168b84e3a8a3cbbdbba98e3bcdbf7ada Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 20 May 2024 11:19:54 +0100 Subject: [PATCH 21/53] chore(developer): refactor CompMsg.cpp to use a std::map --- developer/src/kmcmplib/src/CompMsg.cpp | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/developer/src/kmcmplib/src/CompMsg.cpp b/developer/src/kmcmplib/src/CompMsg.cpp index 86a9b4d475..5bfbeb9a09 100644 --- a/developer/src/kmcmplib/src/CompMsg.cpp +++ b/developer/src/kmcmplib/src/CompMsg.cpp @@ -1,11 +1,7 @@ #include +#include -struct CompilerError { - KMX_DWORD ErrorCode; - const KMX_CHAR* Text; - }; - -const struct CompilerError CompilerErrors[] = { +std::map CompilerErrorMap = { { CERR_InvalidLayoutLine , "Invalid 'layout' command"}, { CERR_NoVersionLine , "No version line found for file"}, { CERR_InvalidGroupLine , "Invalid 'group' command"}, @@ -150,14 +146,8 @@ const struct CompilerError CompilerErrors[] = { { CWARN_VirtualKeyInOutput , "Virtual keys are not supported in output"}, { 0, nullptr } - }; +}; -KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) -{ - for(int i = 0; CompilerErrors[i].ErrorCode; i++) { - if(CompilerErrors[i].ErrorCode == code) { - return ( KMX_CHAR*) CompilerErrors[i].Text; - } - } - return nullptr; +KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) { + return (KMX_CHAR*) CompilerErrorMap[code]; } From 213d7b9a57365aca1f1ecb853e3513cf76dc6f1c Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 20 May 2024 11:26:05 +0100 Subject: [PATCH 22/53] chore(developer): reduce indent on CompMsg error messages --- developer/src/kmcmplib/src/CompMsg.cpp | 282 ++++++++++++------------- 1 file changed, 141 insertions(+), 141 deletions(-) diff --git a/developer/src/kmcmplib/src/CompMsg.cpp b/developer/src/kmcmplib/src/CompMsg.cpp index 5bfbeb9a09..2a9c5c6867 100644 --- a/developer/src/kmcmplib/src/CompMsg.cpp +++ b/developer/src/kmcmplib/src/CompMsg.cpp @@ -2,150 +2,150 @@ #include std::map CompilerErrorMap = { - { CERR_InvalidLayoutLine , "Invalid 'layout' command"}, - { CERR_NoVersionLine , "No version line found for file"}, - { CERR_InvalidGroupLine , "Invalid 'group' command"}, - { CERR_InvalidStoreLine , "Invalid 'store' command"}, - { CERR_InvalidCodeInKeyPartOfRule , "Invalid command or code found in key part of rule"}, - { CERR_InvalidDeadkey , "Invalid 'deadkey' or 'dk' command"}, - { CERR_InvalidValue , "Invalid value in extended string"}, - { CERR_ZeroLengthString , "A string of zero characters was found"}, - { CERR_TooManyIndexToKeyRefs , "Too many index commands refering to key string"}, - { CERR_UnterminatedString , "Unterminated string in line"}, - { CERR_StringInVirtualKeySection , "extend string illegal in virtual key section"}, - { CERR_AnyInVirtualKeySection , "'any' command is illegal in virtual key section"}, - { CERR_InvalidAny , "Invalid 'any' command"}, - { CERR_StoreDoesNotExist , "Store referenced does not exist"}, - { CERR_BeepInVirtualKeySection , "'beep' command is illegal in virtual key section"}, - { CERR_IndexInVirtualKeySection , "'index' command is illegal in virtual key section"}, - { CERR_BadCallParams , "CompileKeyboardFile was called with bad parameters"}, - { CERR_InfileNotExist , "Cannot find the input file"}, - // { CERR_CannotCreateOutfile , "Cannot open output file for writing"}, unused - { CERR_UnableToWriteFully , "Unable to write the file completely"}, - { CERR_CannotReadInfile , "Cannot read the input file"}, - { CERR_SomewhereIGotItWrong , "Internal error: contact Keyman"}, - { CERR_BufferOverflow , "The compiler memory buffer overflowed"}, - { CERR_Break , "Compiler interrupted by user"}, - { CERR_CannotAllocateMemory , "Out of memory"}, - { CERR_InvalidBitmapLine , "Invalid 'bitmaps' command"}, - { CERR_CannotReadBitmapFile , "Cannot open the bitmap or icon file for reading"}, - { CERR_IndexDoesNotPointToAny , "An index() in the output does not have a corresponding any() statement"}, - { CERR_ReservedCharacter , "A reserved character was found"}, - { CERR_InvalidCharacter , "A character was found that is outside the valid Unicode range (U+0000 - U+10FFFF)"}, - { CERR_InvalidCall , "The 'call' command is invalid"}, - { CERR_CallInVirtualKeySection , "'call' command is illegal in virtual key section"}, - { CERR_CodeInvalidInKeyStore , "The command is invalid inside a store that is used in a key part of the rule"}, - { CERR_CannotLoadIncludeFile , "Cannot load the included file: it is either invalid or does not exist"}, - { CERR_60FeatureOnly_EthnologueCode , "EthnologueCode system store requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_MnemonicLayout , "MnemonicLayout functionality requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_OldCharPosMatching , "OldCharPosMatching system store requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_NamedCodes , "Named character constants requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_Contextn , "Context(n) requires VERSION 6.0 or higher"}, - { CERR_501FeatureOnly_Call , "Call() requires VERSION 5.01 or higher"}, - { CERR_InvalidNamedCode , "Invalid named code constant"}, - { CERR_InvalidSystemStore , "Invalid system store name found"}, - { CERR_60FeatureOnly_VirtualCharKey , "Virtual character keys require VERSION 6.0 or higher"}, - { CERR_VersionAlreadyIncluded , "Only one VERSION or store(version) line allowed in a source file."}, - { CERR_70FeatureOnly , "This feature requires store(version) '7.0' or higher"}, - { CERR_80FeatureOnly , "This feature requires store(version) '8.0' or higher"}, - { CERR_InvalidInVirtualKeySection , "This statement is not valid in a virtual key section"}, - { CERR_InvalidIf , "The if() statement is not valid"}, - { CERR_InvalidReset , "The reset() statement is not valid"}, - { CERR_InvalidSet , "The set() statement is not valid"}, - { CERR_InvalidSave , "The save() statement is not valid"}, - { CERR_InvalidEthnologueCode , "Invalid ethnologuecode format"}, - { CERR_90FeatureOnly_IfSystemStores , "if(store) requires store(version) '9.0' or higher"}, - { CERR_IfSystemStore_NotFound , "System store in if() not found"}, - { CERR_90FeatureOnly_SetSystemStores , "set(store) requires store(version) '9.0' or higher"}, - { CERR_SetSystemStore_NotFound , "System store in set() not found"}, - { CERR_90FeatureOnlyVirtualKeyDictionary , "Custom virtual key names require store(version) '9.0'"}, - { CERR_InvalidIndex , "Invalid 'index' command"}, - { CERR_OutsInVirtualKeySection , "'outs' command is illegal in virtual key section"}, - { CERR_InvalidOuts , "Invalid 'outs' command"}, - { CERR_ContextInVirtualKeySection , "'context' command is illegal in virtual key section"}, - { CERR_InvalidUse , "Invalid 'use' command"}, - { CERR_GroupDoesNotExist , "Group does not exist"}, - { CERR_VirtualKeyNotAllowedHere , "Virtual key is not allowed here"}, - { CERR_InvalidSwitch , "Invalid 'switch' command"}, - { CERR_NoTokensFound , "No tokens found in line"}, - { CERR_InvalidLineContinuation , "Invalid line continuation"}, - { CERR_LineTooLong , "Line too long"}, - { CERR_InvalidCopyright , "Invalid 'copyright' command"}, - { CERR_CodeInvalidInThisSection , "This line is invalid in this section of the file"}, - { CERR_InvalidMessage , "Invalid 'message' command"}, - { CERR_InvalidLanguageName , "Invalid 'languagename' command"}, - { CERR_EndOfFile , "(no error - reserved code)"}, - { CERR_InvalidToken , "Invalid token found"}, - { CERR_InvalidBegin , "Invalid 'begin' command"}, - { CERR_InvalidName , "Invalid 'name' command"}, - { CERR_InvalidVersion , "Invalid 'version' command"}, - { CERR_InvalidLanguageLine , "Invalid 'language' command"}, - { CERR_LayoutButNoLanguage , "Layout command found but no language command"}, - { CERR_CannotCreateTempfile , "Cannot create temp file"}, - { CERR_90FeatureOnlyLayoutFile , "Touch layout file reference requires store(version) '9.0'or higher"}, - { CERR_90FeatureOnlyKeyboardVersion , "KeyboardVersion system store requires store(version) '9.0'or higher"}, - { CERR_KeyboardVersionFormatInvalid , "KeyboardVersion format is invalid, expecting dot-separated integers"}, - { CERR_ContextExHasInvalidOffset , "context() statement has offset out of range"}, - { CERR_90FeatureOnlyEmbedCSS , "Embedding CSS requires store(version) '9.0'or higher"}, - { CERR_90FeatureOnlyTargets , "TARGETS system store requires store(version) '9.0'or higher"}, - { CERR_ContextAndIndexInvalidInMatchNomatch , "context and index statements cannot be used in a match or nomatch statement"}, - { CERR_140FeatureOnlyContextAndNotAnyWeb , "For web and touch platforms, context() statement referring to notany() requires store(version) '14.0'or higher"}, - { CERR_ExpansionMustFollowCharacterOrVKey , "An expansion must follow a character or a virtual key"}, - { CERR_VKeyExpansionMustBeFollowedByVKey , "A virtual key expansion must be terminated by a virtual key"}, - { CERR_CharacterExpansionMustBeFollowedByCharacter , "A character expansion must be terminated by a character key"}, - { CERR_VKeyExpansionMustUseConsistentShift , "A virtual key expansion must use the same shift state for both terminators"}, - { CERR_ExpansionMustBePositive , "An expansion must have positive difference (i.e. A-Z, not Z-A)"}, - { CERR_CasedKeysMustContainOnlyVirtualKeys , "The &CasedKeys system store must contain only virtual keys or characters found on a US English keyboard"}, - { CERR_CasedKeysMustNotIncludeShiftStates , "The &CasedKeys system store must not include shift states"}, - { CERR_CasedKeysNotSupportedWithMnemonicLayout , "The &CasedKeys system store is not supported with mnemonic layouts"}, - { CERR_CannotUseReadWriteGroupFromReadonlyGroup , "Group used from a readonly group must also be readonly"}, - { CERR_StatementNotPermittedInReadonlyGroup , "Statement is not permitted in output of readonly group"}, - { CERR_OutputInReadonlyGroup , "Output is not permitted in a readonly group"}, - { CERR_NewContextGroupMustBeReadonly , "Group used in begin newContext must be readonly"}, - { CERR_PostKeystrokeGroupMustBeReadonly , "Group used in begin postKeystroke must be readonly"}, - { CERR_DuplicateGroup , "A group with this name has already been defined."}, - { CERR_DuplicateStore , "A store with this name has already been defined."}, - { CERR_RepeatedBegin , "Begin has already been set"}, - { CERR_VirtualKeyInContext , "Virtual keys are not permitted in context"}, - { CERR_OutsTooLong , "Store cannot be inserted with outs() as it makes the extended string too long" }, - { CERR_ExtendedStringTooLong , "Extended string is too long" }, - { CERR_VirtualKeyExpansionTooLong , "Virtual key expansion is too large" }, - { CERR_CharacterRangeTooLong , "Character range is too large and cannot be expanded" }, + { CERR_InvalidLayoutLine , "Invalid 'layout' command"}, + { CERR_NoVersionLine , "No version line found for file"}, + { CERR_InvalidGroupLine , "Invalid 'group' command"}, + { CERR_InvalidStoreLine , "Invalid 'store' command"}, + { CERR_InvalidCodeInKeyPartOfRule , "Invalid command or code found in key part of rule"}, + { CERR_InvalidDeadkey , "Invalid 'deadkey' or 'dk' command"}, + { CERR_InvalidValue , "Invalid value in extended string"}, + { CERR_ZeroLengthString , "A string of zero characters was found"}, + { CERR_TooManyIndexToKeyRefs , "Too many index commands refering to key string"}, + { CERR_UnterminatedString , "Unterminated string in line"}, + { CERR_StringInVirtualKeySection , "extend string illegal in virtual key section"}, + { CERR_AnyInVirtualKeySection , "'any' command is illegal in virtual key section"}, + { CERR_InvalidAny , "Invalid 'any' command"}, + { CERR_StoreDoesNotExist , "Store referenced does not exist"}, + { CERR_BeepInVirtualKeySection , "'beep' command is illegal in virtual key section"}, + { CERR_IndexInVirtualKeySection , "'index' command is illegal in virtual key section"}, + { CERR_BadCallParams , "CompileKeyboardFile was called with bad parameters"}, + { CERR_InfileNotExist , "Cannot find the input file"}, + // { CERR_CannotCreateOutfile , "Cannot open output file for writing"}, unused + { CERR_UnableToWriteFully , "Unable to write the file completely"}, + { CERR_CannotReadInfile , "Cannot read the input file"}, + { CERR_SomewhereIGotItWrong , "Internal error: contact Keyman"}, + { CERR_BufferOverflow , "The compiler memory buffer overflowed"}, + { CERR_Break , "Compiler interrupted by user"}, + { CERR_CannotAllocateMemory , "Out of memory"}, + { CERR_InvalidBitmapLine , "Invalid 'bitmaps' command"}, + { CERR_CannotReadBitmapFile , "Cannot open the bitmap or icon file for reading"}, + { CERR_IndexDoesNotPointToAny , "An index() in the output does not have a corresponding any() statement"}, + { CERR_ReservedCharacter , "A reserved character was found"}, + { CERR_InvalidCharacter , "A character was found that is outside the valid Unicode range (U+0000 - U+10FFFF)"}, + { CERR_InvalidCall , "The 'call' command is invalid"}, + { CERR_CallInVirtualKeySection , "'call' command is illegal in virtual key section"}, + { CERR_CodeInvalidInKeyStore , "The command is invalid inside a store that is used in a key part of the rule"}, + { CERR_CannotLoadIncludeFile , "Cannot load the included file: it is either invalid or does not exist"}, + { CERR_60FeatureOnly_EthnologueCode , "EthnologueCode system store requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_MnemonicLayout , "MnemonicLayout functionality requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_OldCharPosMatching , "OldCharPosMatching system store requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_NamedCodes , "Named character constants requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_Contextn , "Context(n) requires VERSION 6.0 or higher"}, + { CERR_501FeatureOnly_Call , "Call() requires VERSION 5.01 or higher"}, + { CERR_InvalidNamedCode , "Invalid named code constant"}, + { CERR_InvalidSystemStore , "Invalid system store name found"}, + { CERR_60FeatureOnly_VirtualCharKey , "Virtual character keys require VERSION 6.0 or higher"}, + { CERR_VersionAlreadyIncluded , "Only one VERSION or store(version) line allowed in a source file."}, + { CERR_70FeatureOnly , "This feature requires store(version) '7.0' or higher"}, + { CERR_80FeatureOnly , "This feature requires store(version) '8.0' or higher"}, + { CERR_InvalidInVirtualKeySection , "This statement is not valid in a virtual key section"}, + { CERR_InvalidIf , "The if() statement is not valid"}, + { CERR_InvalidReset , "The reset() statement is not valid"}, + { CERR_InvalidSet , "The set() statement is not valid"}, + { CERR_InvalidSave , "The save() statement is not valid"}, + { CERR_InvalidEthnologueCode , "Invalid ethnologuecode format"}, + { CERR_90FeatureOnly_IfSystemStores , "if(store) requires store(version) '9.0' or higher"}, + { CERR_IfSystemStore_NotFound , "System store in if() not found"}, + { CERR_90FeatureOnly_SetSystemStores , "set(store) requires store(version) '9.0' or higher"}, + { CERR_SetSystemStore_NotFound , "System store in set() not found"}, + { CERR_90FeatureOnlyVirtualKeyDictionary , "Custom virtual key names require store(version) '9.0'"}, + { CERR_InvalidIndex , "Invalid 'index' command"}, + { CERR_OutsInVirtualKeySection , "'outs' command is illegal in virtual key section"}, + { CERR_InvalidOuts , "Invalid 'outs' command"}, + { CERR_ContextInVirtualKeySection , "'context' command is illegal in virtual key section"}, + { CERR_InvalidUse , "Invalid 'use' command"}, + { CERR_GroupDoesNotExist , "Group does not exist"}, + { CERR_VirtualKeyNotAllowedHere , "Virtual key is not allowed here"}, + { CERR_InvalidSwitch , "Invalid 'switch' command"}, + { CERR_NoTokensFound , "No tokens found in line"}, + { CERR_InvalidLineContinuation , "Invalid line continuation"}, + { CERR_LineTooLong , "Line too long"}, + { CERR_InvalidCopyright , "Invalid 'copyright' command"}, + { CERR_CodeInvalidInThisSection , "This line is invalid in this section of the file"}, + { CERR_InvalidMessage , "Invalid 'message' command"}, + { CERR_InvalidLanguageName , "Invalid 'languagename' command"}, + { CERR_EndOfFile , "(no error - reserved code)"}, + { CERR_InvalidToken , "Invalid token found"}, + { CERR_InvalidBegin , "Invalid 'begin' command"}, + { CERR_InvalidName , "Invalid 'name' command"}, + { CERR_InvalidVersion , "Invalid 'version' command"}, + { CERR_InvalidLanguageLine , "Invalid 'language' command"}, + { CERR_LayoutButNoLanguage , "Layout command found but no language command"}, + { CERR_CannotCreateTempfile , "Cannot create temp file"}, + { CERR_90FeatureOnlyLayoutFile , "Touch layout file reference requires store(version) '9.0'or higher"}, + { CERR_90FeatureOnlyKeyboardVersion , "KeyboardVersion system store requires store(version) '9.0'or higher"}, + { CERR_KeyboardVersionFormatInvalid , "KeyboardVersion format is invalid, expecting dot-separated integers"}, + { CERR_ContextExHasInvalidOffset , "context() statement has offset out of range"}, + { CERR_90FeatureOnlyEmbedCSS , "Embedding CSS requires store(version) '9.0'or higher"}, + { CERR_90FeatureOnlyTargets , "TARGETS system store requires store(version) '9.0'or higher"}, + { CERR_ContextAndIndexInvalidInMatchNomatch , "context and index statements cannot be used in a match or nomatch statement"}, + { CERR_140FeatureOnlyContextAndNotAnyWeb , "For web and touch platforms, context() statement referring to notany() requires store(version) '14.0'or higher"}, + { CERR_ExpansionMustFollowCharacterOrVKey , "An expansion must follow a character or a virtual key"}, + { CERR_VKeyExpansionMustBeFollowedByVKey , "A virtual key expansion must be terminated by a virtual key"}, + { CERR_CharacterExpansionMustBeFollowedByCharacter , "A character expansion must be terminated by a character key"}, + { CERR_VKeyExpansionMustUseConsistentShift , "A virtual key expansion must use the same shift state for both terminators"}, + { CERR_ExpansionMustBePositive , "An expansion must have positive difference (i.e. A-Z, not Z-A)"}, + { CERR_CasedKeysMustContainOnlyVirtualKeys , "The &CasedKeys system store must contain only virtual keys or characters found on a US English keyboard"}, + { CERR_CasedKeysMustNotIncludeShiftStates , "The &CasedKeys system store must not include shift states"}, + { CERR_CasedKeysNotSupportedWithMnemonicLayout , "The &CasedKeys system store is not supported with mnemonic layouts"}, + { CERR_CannotUseReadWriteGroupFromReadonlyGroup , "Group used from a readonly group must also be readonly"}, + { CERR_StatementNotPermittedInReadonlyGroup , "Statement is not permitted in output of readonly group"}, + { CERR_OutputInReadonlyGroup , "Output is not permitted in a readonly group"}, + { CERR_NewContextGroupMustBeReadonly , "Group used in begin newContext must be readonly"}, + { CERR_PostKeystrokeGroupMustBeReadonly , "Group used in begin postKeystroke must be readonly"}, + { CERR_DuplicateGroup , "A group with this name has already been defined."}, + { CERR_DuplicateStore , "A store with this name has already been defined."}, + { CERR_RepeatedBegin , "Begin has already been set"}, + { CERR_VirtualKeyInContext , "Virtual keys are not permitted in context"}, + { CERR_OutsTooLong , "Store cannot be inserted with outs() as it makes the extended string too long" }, + { CERR_ExtendedStringTooLong , "Extended string is too long" }, + { CERR_VirtualKeyExpansionTooLong , "Virtual key expansion is too large" }, + { CERR_CharacterRangeTooLong , "Character range is too large and cannot be expanded" }, - { CHINT_UnreachableRule , "This rule will never be matched as another rule takes precedence"}, - { CHINT_NonUnicodeFile , "Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8"}, + { CHINT_UnreachableRule , "This rule will never be matched as another rule takes precedence"}, + { CHINT_NonUnicodeFile , "Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8"}, - { CWARN_TooManyWarnings , "Too many warnings or errors"}, - { CWARN_OldVersion , "The keyboard file is an old version"}, - { CWARN_BitmapNotUsed , "The 'bitmaps' statement is obsolete and only the first bitmap referred to will be used, you should use 'bitmap'."}, - { CWARN_CustomLanguagesNotSupported , "Languages over 0x1FF, 0x1F are not supported correctly by Windows. You should use no LANGUAGE line instead."}, - { CWARN_KeyBadLength , "There are too many characters in the keystroke part of the rule."}, - { CWARN_IndexStoreShort , "The store referenced in index() is shorter than the store referenced in any()"}, - { CWARN_UnicodeInANSIGroup , "A Unicode character was found in an ANSI group"}, - { CWARN_ANSIInUnicodeGroup , "An ANSI character was found in a Unicode group"}, - { CWARN_UnicodeSurrogateUsed , "A Unicode surrogate character was found. You should use Unicode scalar values to represent values > U+FFFF"}, - { CWARN_ReservedCharacter , "A Unicode character was found that should not be used"}, - { CWARN_Info , "Information"}, - { CWARN_VirtualKeyWithMnemonicLayout , "Virtual key used instead of virtual character key with a mnemonic layout"}, - { CWARN_VirtualCharKeyWithPositionalLayout , "Virtual character key used with a positional layout instead of mnemonic layout"}, - { CWARN_StoreAlreadyUsedAsOptionOrCall , "Store already used as an option or in a call statement and should not be used as a normal store"}, - { CWARN_StoreAlreadyUsedAsStoreOrCall , "Store already used as a normal store or in a call statement and should not be used as an option"}, - { CWARN_StoreAlreadyUsedAsStoreOrOption , "Store already used as a normal store or as an option and should not be used in a call statement"}, - { CWARN_PunctuationInEthnologueCode , "Punctuation should not be used to separate Ethnologue codes; instead use spaces"}, - { CWARN_PlatformNotInTargets , "The specified platform is not a target platform"}, - { CWARN_HeaderStatementIsDeprecated , "Header statements are deprecated; use instead the equivalent system store"}, - { CWARN_UseNotLastStatementInRule , "A rule with use() statements in the output should not have other content following the use() statements"}, - { CWARN_KVKFileIsInSourceFormat , ".kvk file should be binary but is an XML file"}, - { CWARN_DontMixChiralAndNonChiralModifiers , "Don't mix the use of left/right modifiers with non-left/right modifiers in the same platform"}, - { CWARN_MixingLeftAndRightModifiers , "Left and right modifiers should not both be used in the same rule"}, - { CWARN_LanguageHeadersDeprecatedInKeyman10 , "This language header has been deprecated in Keyman 10. Instead, add language metadata in the package file"}, - { CWARN_HotkeyHasInvalidModifier , "Hotkey has modifiers that are not supported. Use only SHIFT, CTRL and ALT"}, - { 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"}, + { CWARN_TooManyWarnings , "Too many warnings or errors"}, + { CWARN_OldVersion , "The keyboard file is an old version"}, + { CWARN_BitmapNotUsed , "The 'bitmaps' statement is obsolete and only the first bitmap referred to will be used, you should use 'bitmap'."}, + { CWARN_CustomLanguagesNotSupported , "Languages over 0x1FF, 0x1F are not supported correctly by Windows. You should use no LANGUAGE line instead."}, + { CWARN_KeyBadLength , "There are too many characters in the keystroke part of the rule."}, + { CWARN_IndexStoreShort , "The store referenced in index() is shorter than the store referenced in any()"}, + { CWARN_UnicodeInANSIGroup , "A Unicode character was found in an ANSI group"}, + { CWARN_ANSIInUnicodeGroup , "An ANSI character was found in a Unicode group"}, + { CWARN_UnicodeSurrogateUsed , "A Unicode surrogate character was found. You should use Unicode scalar values to represent values > U+FFFF"}, + { CWARN_ReservedCharacter , "A Unicode character was found that should not be used"}, + { CWARN_Info , "Information"}, + { CWARN_VirtualKeyWithMnemonicLayout , "Virtual key used instead of virtual character key with a mnemonic layout"}, + { CWARN_VirtualCharKeyWithPositionalLayout , "Virtual character key used with a positional layout instead of mnemonic layout"}, + { CWARN_StoreAlreadyUsedAsOptionOrCall , "Store already used as an option or in a call statement and should not be used as a normal store"}, + { CWARN_StoreAlreadyUsedAsStoreOrCall , "Store already used as a normal store or in a call statement and should not be used as an option"}, + { CWARN_StoreAlreadyUsedAsStoreOrOption , "Store already used as a normal store or as an option and should not be used in a call statement"}, + { CWARN_PunctuationInEthnologueCode , "Punctuation should not be used to separate Ethnologue codes; instead use spaces"}, + { CWARN_PlatformNotInTargets , "The specified platform is not a target platform"}, + { CWARN_HeaderStatementIsDeprecated , "Header statements are deprecated; use instead the equivalent system store"}, + { CWARN_UseNotLastStatementInRule , "A rule with use() statements in the output should not have other content following the use() statements"}, + { CWARN_KVKFileIsInSourceFormat , ".kvk file should be binary but is an XML file"}, + { CWARN_DontMixChiralAndNonChiralModifiers , "Don't mix the use of left/right modifiers with non-left/right modifiers in the same platform"}, + { CWARN_MixingLeftAndRightModifiers , "Left and right modifiers should not both be used in the same rule"}, + { CWARN_LanguageHeadersDeprecatedInKeyman10 , "This language header has been deprecated in Keyman 10. Instead, add language metadata in the package file"}, + { CWARN_HotkeyHasInvalidModifier , "Hotkey has modifiers that are not supported. Use only SHIFT, CTRL and ALT"}, + { 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 } + { 0, nullptr } }; KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) { From 309727523e6a0495d7eb61fc0fd6528954b27c05 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 20 May 2024 11:47:19 +0100 Subject: [PATCH 23/53] chore(developer): add AddCompileWarning test --- .../src/kmcmplib/tests/gtest-compiler-test.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index a76fa0ea20..913734b74b 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -20,6 +20,7 @@ extern kmcmp_CompilerMessageProc msgproc; namespace kmcmp { extern int nErrors; extern int ErrChr; + KMX_BOOL AddCompileWarning(char* buf); } #define ERR_EXTRA_LIB_LEN 256 @@ -41,7 +42,7 @@ class CompilerTest : public testing::Test { public: static KMX_CHAR szText_stub[]; - static int msgproc_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { + static int msgproc_true_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { strcpy(szText_stub, szText); return 1; }; @@ -67,8 +68,17 @@ TEST_F(CompilerTest, wstrtostr_test) { // KMX_BOOL kmcmp::AddCompileWarning(PKMX_CHAR buf) +TEST_F(CompilerTest, AddCompileWarning_test) { + msgproc = msgproc_false_stub; + const char *const WARNING_TEXT = "warning"; + EXPECT_EQ(0, kmcmp::nErrors); + EXPECT_FALSE(kmcmp::AddCompileWarning((PKMX_CHAR)WARNING_TEXT)); + EXPECT_EQ(0, strcmp(WARNING_TEXT, szText_stub)); + EXPECT_EQ(0, kmcmp::nErrors); +}; + TEST_F(CompilerTest, AddCompileError_test) { - msgproc = msgproc_stub; + msgproc = msgproc_true_stub; kmcmp::ErrChr = 0; ErrExtraLIB[0] = '\0'; KMX_CHAR expected[COMPILE_ERROR_MAX_LEN]; From ca09856208aaff1da3bf980c2f6b168a1be76276 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 20 May 2024 11:50:37 +0100 Subject: [PATCH 24/53] chore(developer): restore indent on ComgMsg error messages (for sake of reviewer) --- developer/src/kmcmplib/src/CompMsg.cpp | 284 ++++++++++++------------- 1 file changed, 142 insertions(+), 142 deletions(-) diff --git a/developer/src/kmcmplib/src/CompMsg.cpp b/developer/src/kmcmplib/src/CompMsg.cpp index 2a9c5c6867..6480458fda 100644 --- a/developer/src/kmcmplib/src/CompMsg.cpp +++ b/developer/src/kmcmplib/src/CompMsg.cpp @@ -2,152 +2,152 @@ #include std::map CompilerErrorMap = { - { CERR_InvalidLayoutLine , "Invalid 'layout' command"}, - { CERR_NoVersionLine , "No version line found for file"}, - { CERR_InvalidGroupLine , "Invalid 'group' command"}, - { CERR_InvalidStoreLine , "Invalid 'store' command"}, - { CERR_InvalidCodeInKeyPartOfRule , "Invalid command or code found in key part of rule"}, - { CERR_InvalidDeadkey , "Invalid 'deadkey' or 'dk' command"}, - { CERR_InvalidValue , "Invalid value in extended string"}, - { CERR_ZeroLengthString , "A string of zero characters was found"}, - { CERR_TooManyIndexToKeyRefs , "Too many index commands refering to key string"}, - { CERR_UnterminatedString , "Unterminated string in line"}, - { CERR_StringInVirtualKeySection , "extend string illegal in virtual key section"}, - { CERR_AnyInVirtualKeySection , "'any' command is illegal in virtual key section"}, - { CERR_InvalidAny , "Invalid 'any' command"}, - { CERR_StoreDoesNotExist , "Store referenced does not exist"}, - { CERR_BeepInVirtualKeySection , "'beep' command is illegal in virtual key section"}, - { CERR_IndexInVirtualKeySection , "'index' command is illegal in virtual key section"}, - { CERR_BadCallParams , "CompileKeyboardFile was called with bad parameters"}, - { CERR_InfileNotExist , "Cannot find the input file"}, - // { CERR_CannotCreateOutfile , "Cannot open output file for writing"}, unused - { CERR_UnableToWriteFully , "Unable to write the file completely"}, - { CERR_CannotReadInfile , "Cannot read the input file"}, - { CERR_SomewhereIGotItWrong , "Internal error: contact Keyman"}, - { CERR_BufferOverflow , "The compiler memory buffer overflowed"}, - { CERR_Break , "Compiler interrupted by user"}, - { CERR_CannotAllocateMemory , "Out of memory"}, - { CERR_InvalidBitmapLine , "Invalid 'bitmaps' command"}, - { CERR_CannotReadBitmapFile , "Cannot open the bitmap or icon file for reading"}, - { CERR_IndexDoesNotPointToAny , "An index() in the output does not have a corresponding any() statement"}, - { CERR_ReservedCharacter , "A reserved character was found"}, - { CERR_InvalidCharacter , "A character was found that is outside the valid Unicode range (U+0000 - U+10FFFF)"}, - { CERR_InvalidCall , "The 'call' command is invalid"}, - { CERR_CallInVirtualKeySection , "'call' command is illegal in virtual key section"}, - { CERR_CodeInvalidInKeyStore , "The command is invalid inside a store that is used in a key part of the rule"}, - { CERR_CannotLoadIncludeFile , "Cannot load the included file: it is either invalid or does not exist"}, - { CERR_60FeatureOnly_EthnologueCode , "EthnologueCode system store requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_MnemonicLayout , "MnemonicLayout functionality requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_OldCharPosMatching , "OldCharPosMatching system store requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_NamedCodes , "Named character constants requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_Contextn , "Context(n) requires VERSION 6.0 or higher"}, - { CERR_501FeatureOnly_Call , "Call() requires VERSION 5.01 or higher"}, - { CERR_InvalidNamedCode , "Invalid named code constant"}, - { CERR_InvalidSystemStore , "Invalid system store name found"}, - { CERR_60FeatureOnly_VirtualCharKey , "Virtual character keys require VERSION 6.0 or higher"}, - { CERR_VersionAlreadyIncluded , "Only one VERSION or store(version) line allowed in a source file."}, - { CERR_70FeatureOnly , "This feature requires store(version) '7.0' or higher"}, - { CERR_80FeatureOnly , "This feature requires store(version) '8.0' or higher"}, - { CERR_InvalidInVirtualKeySection , "This statement is not valid in a virtual key section"}, - { CERR_InvalidIf , "The if() statement is not valid"}, - { CERR_InvalidReset , "The reset() statement is not valid"}, - { CERR_InvalidSet , "The set() statement is not valid"}, - { CERR_InvalidSave , "The save() statement is not valid"}, - { CERR_InvalidEthnologueCode , "Invalid ethnologuecode format"}, - { CERR_90FeatureOnly_IfSystemStores , "if(store) requires store(version) '9.0' or higher"}, - { CERR_IfSystemStore_NotFound , "System store in if() not found"}, - { CERR_90FeatureOnly_SetSystemStores , "set(store) requires store(version) '9.0' or higher"}, - { CERR_SetSystemStore_NotFound , "System store in set() not found"}, - { CERR_90FeatureOnlyVirtualKeyDictionary , "Custom virtual key names require store(version) '9.0'"}, - { CERR_InvalidIndex , "Invalid 'index' command"}, - { CERR_OutsInVirtualKeySection , "'outs' command is illegal in virtual key section"}, - { CERR_InvalidOuts , "Invalid 'outs' command"}, - { CERR_ContextInVirtualKeySection , "'context' command is illegal in virtual key section"}, - { CERR_InvalidUse , "Invalid 'use' command"}, - { CERR_GroupDoesNotExist , "Group does not exist"}, - { CERR_VirtualKeyNotAllowedHere , "Virtual key is not allowed here"}, - { CERR_InvalidSwitch , "Invalid 'switch' command"}, - { CERR_NoTokensFound , "No tokens found in line"}, - { CERR_InvalidLineContinuation , "Invalid line continuation"}, - { CERR_LineTooLong , "Line too long"}, - { CERR_InvalidCopyright , "Invalid 'copyright' command"}, - { CERR_CodeInvalidInThisSection , "This line is invalid in this section of the file"}, - { CERR_InvalidMessage , "Invalid 'message' command"}, - { CERR_InvalidLanguageName , "Invalid 'languagename' command"}, - { CERR_EndOfFile , "(no error - reserved code)"}, - { CERR_InvalidToken , "Invalid token found"}, - { CERR_InvalidBegin , "Invalid 'begin' command"}, - { CERR_InvalidName , "Invalid 'name' command"}, - { CERR_InvalidVersion , "Invalid 'version' command"}, - { CERR_InvalidLanguageLine , "Invalid 'language' command"}, - { CERR_LayoutButNoLanguage , "Layout command found but no language command"}, - { CERR_CannotCreateTempfile , "Cannot create temp file"}, - { CERR_90FeatureOnlyLayoutFile , "Touch layout file reference requires store(version) '9.0'or higher"}, - { CERR_90FeatureOnlyKeyboardVersion , "KeyboardVersion system store requires store(version) '9.0'or higher"}, - { CERR_KeyboardVersionFormatInvalid , "KeyboardVersion format is invalid, expecting dot-separated integers"}, - { CERR_ContextExHasInvalidOffset , "context() statement has offset out of range"}, - { CERR_90FeatureOnlyEmbedCSS , "Embedding CSS requires store(version) '9.0'or higher"}, - { CERR_90FeatureOnlyTargets , "TARGETS system store requires store(version) '9.0'or higher"}, - { CERR_ContextAndIndexInvalidInMatchNomatch , "context and index statements cannot be used in a match or nomatch statement"}, - { CERR_140FeatureOnlyContextAndNotAnyWeb , "For web and touch platforms, context() statement referring to notany() requires store(version) '14.0'or higher"}, - { CERR_ExpansionMustFollowCharacterOrVKey , "An expansion must follow a character or a virtual key"}, - { CERR_VKeyExpansionMustBeFollowedByVKey , "A virtual key expansion must be terminated by a virtual key"}, - { CERR_CharacterExpansionMustBeFollowedByCharacter , "A character expansion must be terminated by a character key"}, - { CERR_VKeyExpansionMustUseConsistentShift , "A virtual key expansion must use the same shift state for both terminators"}, - { CERR_ExpansionMustBePositive , "An expansion must have positive difference (i.e. A-Z, not Z-A)"}, - { CERR_CasedKeysMustContainOnlyVirtualKeys , "The &CasedKeys system store must contain only virtual keys or characters found on a US English keyboard"}, - { CERR_CasedKeysMustNotIncludeShiftStates , "The &CasedKeys system store must not include shift states"}, - { CERR_CasedKeysNotSupportedWithMnemonicLayout , "The &CasedKeys system store is not supported with mnemonic layouts"}, - { CERR_CannotUseReadWriteGroupFromReadonlyGroup , "Group used from a readonly group must also be readonly"}, - { CERR_StatementNotPermittedInReadonlyGroup , "Statement is not permitted in output of readonly group"}, - { CERR_OutputInReadonlyGroup , "Output is not permitted in a readonly group"}, - { CERR_NewContextGroupMustBeReadonly , "Group used in begin newContext must be readonly"}, - { CERR_PostKeystrokeGroupMustBeReadonly , "Group used in begin postKeystroke must be readonly"}, - { CERR_DuplicateGroup , "A group with this name has already been defined."}, - { CERR_DuplicateStore , "A store with this name has already been defined."}, - { CERR_RepeatedBegin , "Begin has already been set"}, - { CERR_VirtualKeyInContext , "Virtual keys are not permitted in context"}, - { CERR_OutsTooLong , "Store cannot be inserted with outs() as it makes the extended string too long" }, - { CERR_ExtendedStringTooLong , "Extended string is too long" }, - { CERR_VirtualKeyExpansionTooLong , "Virtual key expansion is too large" }, - { CERR_CharacterRangeTooLong , "Character range is too large and cannot be expanded" }, + { CERR_InvalidLayoutLine , "Invalid 'layout' command"}, + { CERR_NoVersionLine , "No version line found for file"}, + { CERR_InvalidGroupLine , "Invalid 'group' command"}, + { CERR_InvalidStoreLine , "Invalid 'store' command"}, + { CERR_InvalidCodeInKeyPartOfRule , "Invalid command or code found in key part of rule"}, + { CERR_InvalidDeadkey , "Invalid 'deadkey' or 'dk' command"}, + { CERR_InvalidValue , "Invalid value in extended string"}, + { CERR_ZeroLengthString , "A string of zero characters was found"}, + { CERR_TooManyIndexToKeyRefs , "Too many index commands refering to key string"}, + { CERR_UnterminatedString , "Unterminated string in line"}, + { CERR_StringInVirtualKeySection , "extend string illegal in virtual key section"}, + { CERR_AnyInVirtualKeySection , "'any' command is illegal in virtual key section"}, + { CERR_InvalidAny , "Invalid 'any' command"}, + { CERR_StoreDoesNotExist , "Store referenced does not exist"}, + { CERR_BeepInVirtualKeySection , "'beep' command is illegal in virtual key section"}, + { CERR_IndexInVirtualKeySection , "'index' command is illegal in virtual key section"}, + { CERR_BadCallParams , "CompileKeyboardFile was called with bad parameters"}, + { CERR_InfileNotExist , "Cannot find the input file"}, + // { CERR_CannotCreateOutfile , "Cannot open output file for writing"}, unused + { CERR_UnableToWriteFully , "Unable to write the file completely"}, + { CERR_CannotReadInfile , "Cannot read the input file"}, + { CERR_SomewhereIGotItWrong , "Internal error: contact Keyman"}, + { CERR_BufferOverflow , "The compiler memory buffer overflowed"}, + { CERR_Break , "Compiler interrupted by user"}, + { CERR_CannotAllocateMemory , "Out of memory"}, + { CERR_InvalidBitmapLine , "Invalid 'bitmaps' command"}, + { CERR_CannotReadBitmapFile , "Cannot open the bitmap or icon file for reading"}, + { CERR_IndexDoesNotPointToAny , "An index() in the output does not have a corresponding any() statement"}, + { CERR_ReservedCharacter , "A reserved character was found"}, + { CERR_InvalidCharacter , "A character was found that is outside the valid Unicode range (U+0000 - U+10FFFF)"}, + { CERR_InvalidCall , "The 'call' command is invalid"}, + { CERR_CallInVirtualKeySection , "'call' command is illegal in virtual key section"}, + { CERR_CodeInvalidInKeyStore , "The command is invalid inside a store that is used in a key part of the rule"}, + { CERR_CannotLoadIncludeFile , "Cannot load the included file: it is either invalid or does not exist"}, + { CERR_60FeatureOnly_EthnologueCode , "EthnologueCode system store requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_MnemonicLayout , "MnemonicLayout functionality requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_OldCharPosMatching , "OldCharPosMatching system store requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_NamedCodes , "Named character constants requires VERSION 6.0 or higher"}, + { CERR_60FeatureOnly_Contextn , "Context(n) requires VERSION 6.0 or higher"}, + { CERR_501FeatureOnly_Call , "Call() requires VERSION 5.01 or higher"}, + { CERR_InvalidNamedCode , "Invalid named code constant"}, + { CERR_InvalidSystemStore , "Invalid system store name found"}, + { CERR_60FeatureOnly_VirtualCharKey , "Virtual character keys require VERSION 6.0 or higher"}, + { CERR_VersionAlreadyIncluded , "Only one VERSION or store(version) line allowed in a source file."}, + { CERR_70FeatureOnly , "This feature requires store(version) '7.0' or higher"}, + { CERR_80FeatureOnly , "This feature requires store(version) '8.0' or higher"}, + { CERR_InvalidInVirtualKeySection , "This statement is not valid in a virtual key section"}, + { CERR_InvalidIf , "The if() statement is not valid"}, + { CERR_InvalidReset , "The reset() statement is not valid"}, + { CERR_InvalidSet , "The set() statement is not valid"}, + { CERR_InvalidSave , "The save() statement is not valid"}, + { CERR_InvalidEthnologueCode , "Invalid ethnologuecode format"}, + { CERR_90FeatureOnly_IfSystemStores , "if(store) requires store(version) '9.0' or higher"}, + { CERR_IfSystemStore_NotFound , "System store in if() not found"}, + { CERR_90FeatureOnly_SetSystemStores , "set(store) requires store(version) '9.0' or higher"}, + { CERR_SetSystemStore_NotFound , "System store in set() not found"}, + { CERR_90FeatureOnlyVirtualKeyDictionary , "Custom virtual key names require store(version) '9.0'"}, + { CERR_InvalidIndex , "Invalid 'index' command"}, + { CERR_OutsInVirtualKeySection , "'outs' command is illegal in virtual key section"}, + { CERR_InvalidOuts , "Invalid 'outs' command"}, + { CERR_ContextInVirtualKeySection , "'context' command is illegal in virtual key section"}, + { CERR_InvalidUse , "Invalid 'use' command"}, + { CERR_GroupDoesNotExist , "Group does not exist"}, + { CERR_VirtualKeyNotAllowedHere , "Virtual key is not allowed here"}, + { CERR_InvalidSwitch , "Invalid 'switch' command"}, + { CERR_NoTokensFound , "No tokens found in line"}, + { CERR_InvalidLineContinuation , "Invalid line continuation"}, + { CERR_LineTooLong , "Line too long"}, + { CERR_InvalidCopyright , "Invalid 'copyright' command"}, + { CERR_CodeInvalidInThisSection , "This line is invalid in this section of the file"}, + { CERR_InvalidMessage , "Invalid 'message' command"}, + { CERR_InvalidLanguageName , "Invalid 'languagename' command"}, + { CERR_EndOfFile , "(no error - reserved code)"}, + { CERR_InvalidToken , "Invalid token found"}, + { CERR_InvalidBegin , "Invalid 'begin' command"}, + { CERR_InvalidName , "Invalid 'name' command"}, + { CERR_InvalidVersion , "Invalid 'version' command"}, + { CERR_InvalidLanguageLine , "Invalid 'language' command"}, + { CERR_LayoutButNoLanguage , "Layout command found but no language command"}, + { CERR_CannotCreateTempfile , "Cannot create temp file"}, + { CERR_90FeatureOnlyLayoutFile , "Touch layout file reference requires store(version) '9.0'or higher"}, + { CERR_90FeatureOnlyKeyboardVersion , "KeyboardVersion system store requires store(version) '9.0'or higher"}, + { CERR_KeyboardVersionFormatInvalid , "KeyboardVersion format is invalid, expecting dot-separated integers"}, + { CERR_ContextExHasInvalidOffset , "context() statement has offset out of range"}, + { CERR_90FeatureOnlyEmbedCSS , "Embedding CSS requires store(version) '9.0'or higher"}, + { CERR_90FeatureOnlyTargets , "TARGETS system store requires store(version) '9.0'or higher"}, + { CERR_ContextAndIndexInvalidInMatchNomatch , "context and index statements cannot be used in a match or nomatch statement"}, + { CERR_140FeatureOnlyContextAndNotAnyWeb , "For web and touch platforms, context() statement referring to notany() requires store(version) '14.0'or higher"}, + { CERR_ExpansionMustFollowCharacterOrVKey , "An expansion must follow a character or a virtual key"}, + { CERR_VKeyExpansionMustBeFollowedByVKey , "A virtual key expansion must be terminated by a virtual key"}, + { CERR_CharacterExpansionMustBeFollowedByCharacter , "A character expansion must be terminated by a character key"}, + { CERR_VKeyExpansionMustUseConsistentShift , "A virtual key expansion must use the same shift state for both terminators"}, + { CERR_ExpansionMustBePositive , "An expansion must have positive difference (i.e. A-Z, not Z-A)"}, + { CERR_CasedKeysMustContainOnlyVirtualKeys , "The &CasedKeys system store must contain only virtual keys or characters found on a US English keyboard"}, + { CERR_CasedKeysMustNotIncludeShiftStates , "The &CasedKeys system store must not include shift states"}, + { CERR_CasedKeysNotSupportedWithMnemonicLayout , "The &CasedKeys system store is not supported with mnemonic layouts"}, + { CERR_CannotUseReadWriteGroupFromReadonlyGroup , "Group used from a readonly group must also be readonly"}, + { CERR_StatementNotPermittedInReadonlyGroup , "Statement is not permitted in output of readonly group"}, + { CERR_OutputInReadonlyGroup , "Output is not permitted in a readonly group"}, + { CERR_NewContextGroupMustBeReadonly , "Group used in begin newContext must be readonly"}, + { CERR_PostKeystrokeGroupMustBeReadonly , "Group used in begin postKeystroke must be readonly"}, + { CERR_DuplicateGroup , "A group with this name has already been defined."}, + { CERR_DuplicateStore , "A store with this name has already been defined."}, + { CERR_RepeatedBegin , "Begin has already been set"}, + { CERR_VirtualKeyInContext , "Virtual keys are not permitted in context"}, + { CERR_OutsTooLong , "Store cannot be inserted with outs() as it makes the extended string too long" }, + { CERR_ExtendedStringTooLong , "Extended string is too long" }, + { CERR_VirtualKeyExpansionTooLong , "Virtual key expansion is too large" }, + { CERR_CharacterRangeTooLong , "Character range is too large and cannot be expanded" }, - { CHINT_UnreachableRule , "This rule will never be matched as another rule takes precedence"}, - { CHINT_NonUnicodeFile , "Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8"}, + { CHINT_UnreachableRule , "This rule will never be matched as another rule takes precedence"}, + { CHINT_NonUnicodeFile , "Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8"}, - { CWARN_TooManyWarnings , "Too many warnings or errors"}, - { CWARN_OldVersion , "The keyboard file is an old version"}, - { CWARN_BitmapNotUsed , "The 'bitmaps' statement is obsolete and only the first bitmap referred to will be used, you should use 'bitmap'."}, - { CWARN_CustomLanguagesNotSupported , "Languages over 0x1FF, 0x1F are not supported correctly by Windows. You should use no LANGUAGE line instead."}, - { CWARN_KeyBadLength , "There are too many characters in the keystroke part of the rule."}, - { CWARN_IndexStoreShort , "The store referenced in index() is shorter than the store referenced in any()"}, - { CWARN_UnicodeInANSIGroup , "A Unicode character was found in an ANSI group"}, - { CWARN_ANSIInUnicodeGroup , "An ANSI character was found in a Unicode group"}, - { CWARN_UnicodeSurrogateUsed , "A Unicode surrogate character was found. You should use Unicode scalar values to represent values > U+FFFF"}, - { CWARN_ReservedCharacter , "A Unicode character was found that should not be used"}, - { CWARN_Info , "Information"}, - { CWARN_VirtualKeyWithMnemonicLayout , "Virtual key used instead of virtual character key with a mnemonic layout"}, - { CWARN_VirtualCharKeyWithPositionalLayout , "Virtual character key used with a positional layout instead of mnemonic layout"}, - { CWARN_StoreAlreadyUsedAsOptionOrCall , "Store already used as an option or in a call statement and should not be used as a normal store"}, - { CWARN_StoreAlreadyUsedAsStoreOrCall , "Store already used as a normal store or in a call statement and should not be used as an option"}, - { CWARN_StoreAlreadyUsedAsStoreOrOption , "Store already used as a normal store or as an option and should not be used in a call statement"}, - { CWARN_PunctuationInEthnologueCode , "Punctuation should not be used to separate Ethnologue codes; instead use spaces"}, - { CWARN_PlatformNotInTargets , "The specified platform is not a target platform"}, - { CWARN_HeaderStatementIsDeprecated , "Header statements are deprecated; use instead the equivalent system store"}, - { CWARN_UseNotLastStatementInRule , "A rule with use() statements in the output should not have other content following the use() statements"}, - { CWARN_KVKFileIsInSourceFormat , ".kvk file should be binary but is an XML file"}, - { CWARN_DontMixChiralAndNonChiralModifiers , "Don't mix the use of left/right modifiers with non-left/right modifiers in the same platform"}, - { CWARN_MixingLeftAndRightModifiers , "Left and right modifiers should not both be used in the same rule"}, - { CWARN_LanguageHeadersDeprecatedInKeyman10 , "This language header has been deprecated in Keyman 10. Instead, add language metadata in the package file"}, - { CWARN_HotkeyHasInvalidModifier , "Hotkey has modifiers that are not supported. Use only SHIFT, CTRL and ALT"}, - { 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"}, + { CWARN_TooManyWarnings , "Too many warnings or errors"}, + { CWARN_OldVersion , "The keyboard file is an old version"}, + { CWARN_BitmapNotUsed , "The 'bitmaps' statement is obsolete and only the first bitmap referred to will be used, you should use 'bitmap'."}, + { CWARN_CustomLanguagesNotSupported , "Languages over 0x1FF, 0x1F are not supported correctly by Windows. You should use no LANGUAGE line instead."}, + { CWARN_KeyBadLength , "There are too many characters in the keystroke part of the rule."}, + { CWARN_IndexStoreShort , "The store referenced in index() is shorter than the store referenced in any()"}, + { CWARN_UnicodeInANSIGroup , "A Unicode character was found in an ANSI group"}, + { CWARN_ANSIInUnicodeGroup , "An ANSI character was found in a Unicode group"}, + { CWARN_UnicodeSurrogateUsed , "A Unicode surrogate character was found. You should use Unicode scalar values to represent values > U+FFFF"}, + { CWARN_ReservedCharacter , "A Unicode character was found that should not be used"}, + { CWARN_Info , "Information"}, + { CWARN_VirtualKeyWithMnemonicLayout , "Virtual key used instead of virtual character key with a mnemonic layout"}, + { CWARN_VirtualCharKeyWithPositionalLayout , "Virtual character key used with a positional layout instead of mnemonic layout"}, + { CWARN_StoreAlreadyUsedAsOptionOrCall , "Store already used as an option or in a call statement and should not be used as a normal store"}, + { CWARN_StoreAlreadyUsedAsStoreOrCall , "Store already used as a normal store or in a call statement and should not be used as an option"}, + { CWARN_StoreAlreadyUsedAsStoreOrOption , "Store already used as a normal store or as an option and should not be used in a call statement"}, + { CWARN_PunctuationInEthnologueCode , "Punctuation should not be used to separate Ethnologue codes; instead use spaces"}, + { CWARN_PlatformNotInTargets , "The specified platform is not a target platform"}, + { CWARN_HeaderStatementIsDeprecated , "Header statements are deprecated; use instead the equivalent system store"}, + { CWARN_UseNotLastStatementInRule , "A rule with use() statements in the output should not have other content following the use() statements"}, + { CWARN_KVKFileIsInSourceFormat , ".kvk file should be binary but is an XML file"}, + { CWARN_DontMixChiralAndNonChiralModifiers , "Don't mix the use of left/right modifiers with non-left/right modifiers in the same platform"}, + { CWARN_MixingLeftAndRightModifiers , "Left and right modifiers should not both be used in the same rule"}, + { CWARN_LanguageHeadersDeprecatedInKeyman10 , "This language header has been deprecated in Keyman 10. Instead, add language metadata in the package file"}, + { CWARN_HotkeyHasInvalidModifier , "Hotkey has modifiers that are not supported. Use only SHIFT, CTRL and ALT"}, + { 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 } + { 0, nullptr } }; KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) { - return (KMX_CHAR*) CompilerErrorMap[code]; + return (KMX_CHAR*) CompilerErrorMap[code]; } From 1c08e9d74dc4bd56ba35e27c796fded544ca57f6 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 20 May 2024 17:11:47 +0100 Subject: [PATCH 25/53] chore(developer): add ProcessBeginLine test with initial six test cases --- .../kmcmplib/tests/gtest-compiler-test.cpp | 53 +++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 913734b74b..75d823b4bd 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -11,6 +11,7 @@ PKMX_WCHAR strtowstr(PKMX_STR in); PKMX_STR wstrtostr(PKMX_WCHAR in); KMX_BOOL AddCompileError(KMX_DWORD msg); +KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); bool hasPreamble(std::u16string result); @@ -20,6 +21,7 @@ extern kmcmp_CompilerMessageProc msgproc; namespace kmcmp { extern int nErrors; extern int ErrChr; + extern int BeginLine[4]; KMX_BOOL AddCompileWarning(char* buf); } @@ -30,13 +32,22 @@ class CompilerTest : public testing::Test { protected: CompilerTest() {} ~CompilerTest() override {} - void SetUp() override {} + void SetUp() override { + kmcmp::BeginLine[BEGIN_ANSI] = -1; + kmcmp::BeginLine[BEGIN_UNICODE] = -1; + kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; + kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; + } void TearDown() override { msgproc = NULL; szText_stub[0] = '\0'; kmcmp::nErrors = 0; kmcmp::ErrChr = 0; ErrExtraLIB[0] = '\0'; + kmcmp::BeginLine[BEGIN_ANSI] = -1; + kmcmp::BeginLine[BEGIN_UNICODE] = -1; + kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; + kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; } public: @@ -66,8 +77,6 @@ TEST_F(CompilerTest, wstrtostr_test) { EXPECT_EQ(0, strcmp("", wstrtostr((PKMX_WCHAR)u""))); }; -// KMX_BOOL kmcmp::AddCompileWarning(PKMX_CHAR buf) - TEST_F(CompilerTest, AddCompileWarning_test) { msgproc = msgproc_false_stub; const char *const WARNING_TEXT = "warning"; @@ -132,7 +141,43 @@ TEST_F(CompilerTest, AddCompileError_test) { EXPECT_EQ(6, kmcmp::nErrors); }; -// KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +TEST_F(CompilerTest, ProcessBeginLine_test) { + FILE_KEYBOARD fk; + KMX_WCHAR str[LINESIZE]; + KMX_DWORD msg; + + // CERR_NoTokensFound + str[0] = '\0'; + EXPECT_EQ(CERR_NoTokensFound, ProcessBeginLine(&fk, str)); + + // CERR_InvalidToken + u16cpy(str, u"abc >"); + EXPECT_EQ(CERR_InvalidToken, ProcessBeginLine(&fk, str)); + + // CERR_RepeatedBegin, BEGIN_UNICODE + kmcmp::BeginLine[BEGIN_UNICODE] = 0; // not -1 + u16cpy(str, u" unicode>"); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + kmcmp::BeginLine[BEGIN_UNICODE] = -1; + + // CERR_RepeatedBegin, BEGIN_ANSI + kmcmp::BeginLine[BEGIN_ANSI] = 0; // not -1 + u16cpy(str, u" ansi>"); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + kmcmp::BeginLine[BEGIN_ANSI] = -1; + + // CERR_RepeatedBegin, BEGIN_NEWCONTEXT + kmcmp::BeginLine[BEGIN_NEWCONTEXT] = 0; // not -1 + u16cpy(str, u" newContext>"); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; + + // CERR_RepeatedBegin, BEGIN_POSTKEYSTROKE + kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = 0; // not -1 + u16cpy(str, u" postKeystroke>"); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; +}; TEST_F(CompilerTest, ValidateMatchNomatchOutput_test) { EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput(NULL)); From 474caecab5db8391c91511057717517522e1cb83 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 20 May 2024 17:35:21 +0100 Subject: [PATCH 26/53] chore(developer): correct include paths --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 2 +- developer/src/kmcmplib/tests/gtest-compmsg-test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 75d823b4bd..0168296bef 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -4,9 +4,9 @@ #include "..\src\kmx_u16.h" #include "..\src\compfile.h" #include "..\src\CompMsg.h" +#include "..\..\common\include\kmn_compiler_errors.h" #include "..\..\..\..\common\include\km_types.h" #include "..\..\..\..\common\include\kmx_file.h" -#include "..\..\..\..\common\include\kmn_compiler_errors.h" PKMX_WCHAR strtowstr(PKMX_STR in); PKMX_STR wstrtostr(PKMX_WCHAR in); diff --git a/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp b/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp index aa1f2d8c8f..94f0f40d8d 100644 --- a/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp @@ -1,6 +1,6 @@ #include +#include "..\..\common\include\kmn_compiler_errors.h" #include "..\..\..\..\common\include\km_types.h" -#include "..\..\..\..\common\include\kmn_compiler_errors.h" KMX_CHAR *GetCompilerErrorString(KMX_DWORD code); From 900f248558a8b50822a68c3c71279394348f665e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 May 2024 08:46:52 +0700 Subject: [PATCH 27/53] chore(common): cleanup meson deprecations and warnings Most warnings have been cleaned up: * min meson version is now 1.0 * additional parameters such as check, recursive added * uses now global_source_root() instead of source_root() * catting files on Windows wasn't actually working -- used in unit tests. This is because meson passes paths with forward slashes to cmd.exe `type` command, which doesn't understand them. This is bad, because we were running effectively null tests for the affected tests. Fortunately, the same tests were configured correctly on macOS and Linux, and were all passing, so no serious damage. There is one significant warning left: `WARNING: Project targets '>=1.0' but uses feature deprecated since '0.64.0': copy arg in configure_file. Use fs.copyfile instead` Refer to mesonbuild/meson#12792. I have opened a PR against that to undeprecate `copy` kwarg in a future version of meson. Fixes: #8399 --- core/meson.build | 2 +- core/tests/meson.build | 2 +- core/tests/unit/kmx/cat.bat | 4 ++++ core/tests/unit/kmx/fixtures/binary/meson.build | 4 ++-- core/tests/unit/kmx/meson.build | 6 ++---- core/tests/unit/ldml/invalid-keyboards/meson.build | 10 ++-------- core/tests/unit/ldml/keyboards/meson.build | 4 ++-- core/tests/unit/ldml/meson.build | 6 ------ core/tests/unit/meson.build | 4 ++-- developer/src/kmcmplib/meson.build | 2 +- developer/src/kmcmplib/src/meson.build | 2 +- developer/src/kmcmplib/tests/meson.build | 8 ++++---- linux/ibus-keyman/meson.build | 2 +- linux/keyman-system-service/meson.build | 2 +- 14 files changed, 24 insertions(+), 34 deletions(-) create mode 100644 core/tests/unit/kmx/cat.bat diff --git a/core/meson.build b/core/meson.build index 42b0965763..db405bf122 100644 --- a/core/meson.build +++ b/core/meson.build @@ -13,7 +13,7 @@ project('keyman_core', 'cpp', 'c', 'b_vscrt=static_from_buildtype', 'warning_level=2', 'debug=true'], - meson_version: '>=0.57.0') + meson_version: '>=1.0') # Import our standard compiler defines; this is copied from # /resources/build/standard.meson.build by build.sh, because diff --git a/core/tests/meson.build b/core/tests/meson.build index e2e2997582..84c17d4220 100644 --- a/core/tests/meson.build +++ b/core/tests/meson.build @@ -21,7 +21,7 @@ if get_option('keyman_core_tests') if get_option('default_library') != 'static' ctypes_void_p_size = ['-c', 'import ctypes; print(ctypes.sizeof(ctypes.c_void_p))'] - r = run_command(python, ctypes_void_p_size) + r = run_command(python, ctypes_void_p_size, check: true) python_ctypes_compatible = r.stdout().to_int() == cpp_compiler.sizeof('void *') if not python_ctypes_compatible message('Python ctypes is incompatible with built shared object. Disabling some tests.') diff --git a/core/tests/unit/kmx/cat.bat b/core/tests/unit/kmx/cat.bat new file mode 100644 index 0000000000..a5568e3919 --- /dev/null +++ b/core/tests/unit/kmx/cat.bat @@ -0,0 +1,4 @@ +@echo off +set infile=%1 +set infileb=%infile:/=\% +type %infileb% diff --git a/core/tests/unit/kmx/fixtures/binary/meson.build b/core/tests/unit/kmx/fixtures/binary/meson.build index 46b0e78d31..cf96bc75ce 100644 --- a/core/tests/unit/kmx/fixtures/binary/meson.build +++ b/core/tests/unit/kmx/fixtures/binary/meson.build @@ -17,9 +17,9 @@ binary_tests = [ foreach kbd : binary_tests configure_file( - command: copy_cmd + ['@INPUT@', '@OUTPUT@'], input: kbd + '.kmn', - output: kbd + '.kmn' + output: kbd + '.kmn', + copy: true ) configure_file( diff --git a/core/tests/unit/kmx/meson.build b/core/tests/unit/kmx/meson.build index 7e5ab5b8bc..329e67f5af 100644 --- a/core/tests/unit/kmx/meson.build +++ b/core/tests/unit/kmx/meson.build @@ -89,10 +89,8 @@ kmc_root = meson.current_source_dir() / '../../../../developer/src/kmc/build/src kmc_cmd = [node, '--enable-source-maps', kmc_root] if build_machine.system() == 'windows' - copy_cmd = [find_program('cmd.exe', required: true), '/c', 'copy'] - cat_cmd = [find_program('cmd.exe', required: true), '/c', 'type'] + cat_cmd = [find_program(meson.current_source_dir() / 'cat.bat', required: true)] else - copy_cmd = [find_program('cp', required: true)] cat_cmd = [find_program('cat', required: true)] endif @@ -127,7 +125,7 @@ foreach kbd : tests kbd_src_path = common_test_keyboards_baseline / kbd + '.kmn' content = run_command( - cat_cmd, files(kbd_src_path), + cat_cmd, files(kbd_src_path), check: true, ).stdout().strip() cfg = configuration_data() diff --git a/core/tests/unit/ldml/invalid-keyboards/meson.build b/core/tests/unit/ldml/invalid-keyboards/meson.build index da8fb85ad0..e85646b68e 100644 --- a/core/tests/unit/ldml/invalid-keyboards/meson.build +++ b/core/tests/unit/ldml/invalid-keyboards/meson.build @@ -8,19 +8,13 @@ invalid_tests = [ 'ik_000_null_invalid' ] -if build_machine.system() == 'windows' - copy_cmd = [find_program('cmd.exe', required: true), '/c', 'copy'] -else - copy_cmd = [find_program('cp', required: true)] -endif - # Build all keyboards in output folder foreach kbd : invalid_tests configure_file( - command: copy_cmd + ['@INPUT@', '@OUTPUT@'], input: kbd + '.xml', - output: kbd + '.xml' + output: kbd + '.xml', + copy: true ) configure_file( diff --git a/core/tests/unit/ldml/keyboards/meson.build b/core/tests/unit/ldml/keyboards/meson.build index 25d5d12ac1..15f458c587 100644 --- a/core/tests/unit/ldml/keyboards/meson.build +++ b/core/tests/unit/ldml/keyboards/meson.build @@ -56,8 +56,8 @@ tests += tests_from_cldr # Setup kmc -kmc_root = join_paths(meson.source_root(),'..','developer','src','kmc') -ldml_root = join_paths(meson.source_root(),'..','resources','standards-data','ldml-keyboards','45') +kmc_root = meson.global_source_root() / '../developer/src/kmc' +ldml_root = meson.global_source_root() / '../resources/standards-data/ldml-keyboards/45' ldml_data = join_paths(ldml_root, '3.0') ldml_testdata = join_paths(ldml_root, 'test') kmc_cmd = [node, '--enable-source-maps', kmc_root] diff --git a/core/tests/unit/ldml/meson.build b/core/tests/unit/ldml/meson.build index e0d3d0540d..99af63e1c4 100644 --- a/core/tests/unit/ldml/meson.build +++ b/core/tests/unit/ldml/meson.build @@ -22,12 +22,6 @@ invalid_tests = [] # Setup copying of source files, used in child subdir calls -if build_machine.system() == 'windows' - copy_cmd = [find_program('cmd.exe', required: true), '/c', 'copy'] -else - copy_cmd = [find_program('cp', required: true)] -endif - if node.found() # Note: if node is not available, we cannot build the keyboards; build.sh # emits a warning that the ldml keyboard tests will be skipped diff --git a/core/tests/unit/meson.build b/core/tests/unit/meson.build index e3d9f76607..ee141cc12d 100644 --- a/core/tests/unit/meson.build +++ b/core/tests/unit/meson.build @@ -2,10 +2,10 @@ node = find_program('node', required: true) common_test_files = [ meson.current_source_dir() / 'emscripten_filesystem.cpp', - meson.source_root() / '../common/include/test_color.cpp' + meson.global_source_root() / '../common/include/test_color.cpp' ] -hextobin_root = join_paths(meson.source_root(),'..','common','tools','hextobin','build','hextobin.js') +hextobin_root = meson.global_source_root() / '../common/tools/hextobin/build/hextobin.js' hextobin_cmd = [node, hextobin_root] subdir('json') diff --git a/developer/src/kmcmplib/meson.build b/developer/src/kmcmplib/meson.build index c996981f47..d494e884d9 100644 --- a/developer/src/kmcmplib/meson.build +++ b/developer/src/kmcmplib/meson.build @@ -5,7 +5,7 @@ # project('kmcmplib', 'cpp', 'c', - version: run_command(find_program('getversion.bat', 'getversion.sh')).stdout().strip(), + version: run_command(find_program('getversion.bat', 'getversion.sh'), check: true).stdout().strip(), license: 'MIT', default_options : ['buildtype=release', 'cpp_std=c++14', diff --git a/developer/src/kmcmplib/src/meson.build b/developer/src/kmcmplib/src/meson.build index e3e4efcd48..574f3bb3db 100644 --- a/developer/src/kmcmplib/src/meson.build +++ b/developer/src/kmcmplib/src/meson.build @@ -101,7 +101,7 @@ if cpp_compiler.get_id() == 'emscripten' cpp_args: defns, include_directories: inc, link_args: links + lib_links, - objects: lib.extract_all_objects(), + objects: lib.extract_all_objects(recursive: false), dependencies: icuuc_dep) if get_option('buildtype') == 'release' diff --git a/developer/src/kmcmplib/tests/meson.build b/developer/src/kmcmplib/tests/meson.build index 1ae32590e2..75976576c6 100644 --- a/developer/src/kmcmplib/tests/meson.build +++ b/developer/src/kmcmplib/tests/meson.build @@ -20,7 +20,7 @@ kmcompxtest = executable('kmcompxtest', ['kmcompxtest.cpp','util_filesystem.cpp' include_directories: inc, name_suffix: name_suffix, link_args: links + tests_links, - objects: lib.extract_all_objects(), + objects: lib.extract_all_objects(recursive: false), dependencies: icuuc_dep, ) @@ -129,7 +129,7 @@ if get_option('full_test') endif -common_test_files = [ meson.source_root() / '../../../common/include/test_color.cpp' ] +common_test_files = [ meson.global_source_root() / '../../../common/include/test_color.cpp' ] # Test the API endpoints @@ -138,7 +138,7 @@ apitest = executable('api-test', ['api-test.cpp','util_filesystem.cpp','util_cal include_directories: inc, name_suffix: name_suffix, link_args: links + tests_links, - objects: lib.extract_all_objects(), + objects: lib.extract_all_objects(recursive: false), dependencies: icuuc_dep ) @@ -149,7 +149,7 @@ usetapitest = executable('uset-api-test', 'uset-api-test.cpp', common_test_files include_directories: inc, name_suffix: name_suffix, link_args: links + tests_links, - objects: lib.extract_all_objects(), + objects: lib.extract_all_objects(recursive: false), dependencies: icuuc_dep, ) diff --git a/linux/ibus-keyman/meson.build b/linux/ibus-keyman/meson.build index 5a8958e983..80318708ac 100644 --- a/linux/ibus-keyman/meson.build +++ b/linux/ibus-keyman/meson.build @@ -1,7 +1,7 @@ project('ibus-keyman', 'c', 'cpp', version: run_command('cat', '../../VERSION.md', check: true).stdout().strip(), license: 'GPL-2+', - meson_version: '>=0.53.0') + meson_version: '>=1.0') cc = meson.get_compiler('c') conf = configuration_data() diff --git a/linux/keyman-system-service/meson.build b/linux/keyman-system-service/meson.build index 66da8f9891..596ba48bcd 100644 --- a/linux/keyman-system-service/meson.build +++ b/linux/keyman-system-service/meson.build @@ -1,7 +1,7 @@ project('keyman-system-service', 'c', 'cpp', version: run_command('cat', '../../VERSION.md', check: true).stdout().strip(), license: 'GPL-2+', - meson_version: '>=0.61') + meson_version: '>=1.0') evdev = dependency('libevdev', version: '>= 1.9') systemd = dependency('libsystemd') From 1b3be1540ac67262cdf1b923dc9220699ee031c5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 24 May 2024 14:49:27 +0700 Subject: [PATCH 28/53] chore(common): update linux documentation and control for meson 1.0 --- docs/linux/ibus-keyman.md | 2 +- linux/debian/control | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/linux/ibus-keyman.md b/docs/linux/ibus-keyman.md index ffc7b06c1c..2b6241ccf0 100644 --- a/docs/linux/ibus-keyman.md +++ b/docs/linux/ibus-keyman.md @@ -6,7 +6,7 @@ Source code for Keyman engine for IBus is in [linux/ibus-keyman](../../linux/ibu ## Requirements -meson (>= 0.57) +meson (>= 1.0) ## Building diff --git a/linux/debian/control b/linux/debian/control index 54b186c790..f729999731 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -19,7 +19,7 @@ Build-Depends: libjson-glib-dev (>= 1.4.0), liblocale-gettext-perl, libsystemd-dev, - meson (>= 0.53), + meson (>= 1.0), metacity, ninja-build, perl, From d04ada78a6b85409d3d8789b7bf09dc50fcf6716 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Sat, 25 May 2024 05:35:24 +0700 Subject: [PATCH 29/53] chore(linux): run deb-package sourcepackage job on Ubuntu 24.04 Ubuntu 22.04 has meson 0.61; 24.04 has meson 1.3, so updated the sourcepackage step in deb-packaging to 24.04 to meet min reqs. --- .github/workflows/deb-packaging.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml index 1876be35b7..29f069efd5 100644 --- a/.github/workflows/deb-packaging.yml +++ b/.github/workflows/deb-packaging.yml @@ -24,7 +24,7 @@ jobs: sourcepackage: name: Build source package if: github.repository == 'keymanapp/keyman' - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: VERSION: ${{ steps.version_step.outputs.VERSION }} PRERELEASE_TAG: ${{ steps.prerelease_tag.outputs.PRERELEASE_TAG }} From ec06107fcca0185f8b0d5535b1cb7a75caad61c9 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 28 May 2024 10:23:34 +0100 Subject: [PATCH 30/53] chore(developer): add initial GetRHS test --- .../src/kmcmplib/tests/gtest-compiler-test.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 0168296bef..5165ce82fa 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -14,6 +14,7 @@ KMX_BOOL AddCompileError(KMX_DWORD msg); KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); +KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode); bool hasPreamble(std::u16string result); extern kmcmp_CompilerMessageProc msgproc; @@ -256,6 +257,20 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { // KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataSize) // KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess) // KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode) + +TEST_F(CompilerTest, GetRHS_test) { + FILE_KEYBOARD fk; + KMX_WCHAR str[LINESIZE]; + + // CERR_NoTokensFound, empty string + str[0] = '\0'; + EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, NULL, 0, 0, FALSE)); + + // CERR_NoTokensFound, no '>' + u16cpy(str, u"abc"); + EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, NULL, 0, 0, FALSE)); +} + // void safe_wcsncpy(PKMX_WCHAR out, PKMX_WCHAR in, int cbMax) // KMX_BOOL IsSameToken(PKMX_WCHAR *p, KMX_WCHAR const * token) // static bool endsWith(const std::string& str, const std::string& suffix) From 4b35c815ddf4b44eaf0d67ec1bcdaff4baa8ac79 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 28 May 2024 11:53:41 +0100 Subject: [PATCH 31/53] chore(developer): add additional case to GetRHS test --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 5165ce82fa..16db66af2e 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -256,19 +256,23 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { // KMX_BOOL kmcmp::CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall) // KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataSize) // KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess) -// KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode) TEST_F(CompilerTest, GetRHS_test) { FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; + KMX_WCHAR tstr[128]; // CERR_NoTokensFound, empty string str[0] = '\0'; - EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, NULL, 0, 0, FALSE)); + EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, tstr, 80, 0, FALSE)); // CERR_NoTokensFound, no '>' u16cpy(str, u"abc"); - EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, NULL, 0, 0, FALSE)); + EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, tstr, 80, 0, FALSE)); + + // CERR_None + u16cpy(str, u"> nul c\n"); + EXPECT_EQ(CERR_None, GetRHS(&fk, str, tstr, 80, 0, FALSE)); } // void safe_wcsncpy(PKMX_WCHAR out, PKMX_WCHAR in, int cbMax) From 2b313cb1c985ab8deeab09e7743ce43145f4d48b Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 28 May 2024 16:42:46 +0100 Subject: [PATCH 32/53] chore(developer): add initial GetXStringImpl test --- .../kmcmplib/tests/gtest-compiler-test.cpp | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 16db66af2e..31fd306a16 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -14,6 +14,9 @@ KMX_BOOL AddCompileError(KMX_DWORD msg); KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); +KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, + PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int isUnicode +); KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode); bool hasPreamble(std::u16string result); @@ -239,6 +242,27 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { // KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, // PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int isUnicode // ) + +TEST_F(CompilerTest, GetXStringImpl_test) { + KMX_WCHAR tstr[128]; + FILE_KEYBOARD fk; + KMX_WCHAR str[LINESIZE]; + KMX_WCHAR output[GLOBAL_BUFSIZE]; + PKMX_WCHAR newp = NULL; + + // CERR_BufferOverflow, max=0 + EXPECT_EQ(CERR_BufferOverflow, GetXStringImpl(tstr, &fk, str, u"", output, 0, 0, &newp, FALSE)); + + // CERR_None, no token + str[0] = '\0'; + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + + // CERR_NoTokensFound + u16cpy(str, u""); + //std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE) << std::dec << std::endl; + EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE)); +} + // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // KMX_DWORD process_platform(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From b9b09a23f11b9175f5828f109b60444cdd9b4856 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 30 May 2024 12:22:40 +0100 Subject: [PATCH 33/53] chore(developer): add additional four test cases to GetXStringImpl test, type=0 --- .../kmcmplib/tests/gtest-compiler-test.cpp | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 31fd306a16..6413127fdc 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -257,10 +257,35 @@ TEST_F(CompilerTest, GetXStringImpl_test) { str[0] = '\0'; EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_NoTokensFound + // CERR_NoTokensFound, empty u16cpy(str, u""); - //std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE) << std::dec << std::endl; EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE)); + + // CERR_NoTokensFound, whitespace + u16cpy(str, u" "); + EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE)); + + // type=0, hex 8-bit + u16cpy(str, u"x12"); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); + + // type=0, hex 16-bit + u16cpy(str, u"x1234"); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(u"\u1234", tstr)); + + // std::cerr << "debug" << std::endl; + + // type=0, hex 32-bit + u16cpy(str, u"x10330"); // Gothic A + // std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE) << std::dec << std::endl; + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + // std::cerr << std::hex << tstr[0] << ',' << tstr[1] << std::dec << std::endl; + const KMX_WCHAR tstr_GothicA[] = { 0xD800, 0xDF30, 0 }; // see UTF32ToUTF16 + EXPECT_EQ(0, u16cmp(tstr_GothicA, tstr)); + + // std::cerr << "end debug" << std::endl; } // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From 009450b5625b35998ad68938f903c26f76d854db Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 30 May 2024 15:07:02 +0100 Subject: [PATCH 34/53] chore(developer): add additional three test cases to GetXStringImpl test, type=0 --- .../src/kmcmplib/tests/gtest-compiler-test.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 6413127fdc..91cc87cf74 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -286,6 +286,20 @@ TEST_F(CompilerTest, GetXStringImpl_test) { EXPECT_EQ(0, u16cmp(tstr_GothicA, tstr)); // std::cerr << "end debug" << std::endl; + + // type=0, decimal 8-bit + u16cpy(str, u"d18"); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); + + // type=0, hex capital 8-bit + u16cpy(str, u"X12"); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); + + // type=0, hex 32-bit, CERR_InvalidCharacter + u16cpy(str, u"x110000"); + EXPECT_EQ(CERR_InvalidCharacter, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); } // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From 7b742c52344bc66175e71a04c963c3b92ef9c346 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 30 May 2024 15:51:45 +0100 Subject: [PATCH 35/53] chore(developer): add additional five test cases to GetXStringImpl test, type=0 --- .../kmcmplib/tests/gtest-compiler-test.cpp | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 91cc87cf74..a35389cca5 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -239,9 +239,6 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { // KMX_DWORD GetXString(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, // PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int /*isVKey*/, int isUnicode // ) -// KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, -// PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int isUnicode -// ) TEST_F(CompilerTest, GetXStringImpl_test) { KMX_WCHAR tstr[128]; @@ -300,6 +297,34 @@ TEST_F(CompilerTest, GetXStringImpl_test) { // type=0, hex 32-bit, CERR_InvalidCharacter u16cpy(str, u"x110000"); EXPECT_EQ(CERR_InvalidCharacter, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + + // type=0, dk, valid + u16cpy(str, u"dk(A)"); + EXPECT_EQ(0, (int)fk.cxDeadKeyArray); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + const KMX_WCHAR tstr_dk_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; + EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); + fk.cxDeadKeyArray = 0; + + // type=0, deadkey, valid + u16cpy(str, u"deadkey(A)"); + EXPECT_EQ(0, (int)fk.cxDeadKeyArray); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + const KMX_WCHAR tstr_deadkey_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; + EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); + fk.cxDeadKeyArray = 0; + + // type=0, dk, CERR_InvalidDeadkey, bad character + u16cpy(str, u"dk(%)"); + EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + + // type=0, dk, CERR_InvalidDeadkey, no close delimiter => NULL + u16cpy(str, u"dk("); + EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + + // type=0, dk, CERR_InvalidDeadkey, empty delimiters => empty string + u16cpy(str, u"dk()"); + EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); } // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From f412042d97e61784f6141baf053a8ccf848e6b07 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 30 May 2024 15:59:57 +0100 Subject: [PATCH 36/53] chore(developer): refactor GetXStringImpl test into two, seperating out type=0 --- .../kmcmplib/tests/gtest-compiler-test.cpp | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index a35389cca5..17eb9c1986 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -261,20 +261,18 @@ TEST_F(CompilerTest, GetXStringImpl_test) { // CERR_NoTokensFound, whitespace u16cpy(str, u" "); EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE)); +} - // type=0, hex 8-bit - u16cpy(str, u"x12"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); - EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); - - // type=0, hex 16-bit - u16cpy(str, u"x1234"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); - EXPECT_EQ(0, u16cmp(u"\u1234", tstr)); +TEST_F(CompilerTest, GetXStringImpl_type0_test) { + KMX_WCHAR tstr[128]; + FILE_KEYBOARD fk; + KMX_WCHAR str[LINESIZE]; + KMX_WCHAR output[GLOBAL_BUFSIZE]; + PKMX_WCHAR newp = NULL; // std::cerr << "debug" << std::endl; - // type=0, hex 32-bit + // type=0 ('X' or 'D'), hex 32-bit u16cpy(str, u"x10330"); // Gothic A // std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE) << std::dec << std::endl; EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); @@ -284,21 +282,21 @@ TEST_F(CompilerTest, GetXStringImpl_test) { // std::cerr << "end debug" << std::endl; - // type=0, decimal 8-bit + // type=0 ('X' or 'D'), decimal 8-bit u16cpy(str, u"d18"); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); - // type=0, hex capital 8-bit + // type=0 ('X' or 'D'), hex capital 8-bit u16cpy(str, u"X12"); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); - // type=0, hex 32-bit, CERR_InvalidCharacter + // type=0 ('X' or 'D'), hex 32-bit, CERR_InvalidCharacter u16cpy(str, u"x110000"); EXPECT_EQ(CERR_InvalidCharacter, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); - // type=0, dk, valid + // type=0 ('X' or 'D'), dk, valid u16cpy(str, u"dk(A)"); EXPECT_EQ(0, (int)fk.cxDeadKeyArray); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); @@ -306,7 +304,7 @@ TEST_F(CompilerTest, GetXStringImpl_test) { EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); fk.cxDeadKeyArray = 0; - // type=0, deadkey, valid + // type=0 ('X' or 'D'), deadkey, valid u16cpy(str, u"deadkey(A)"); EXPECT_EQ(0, (int)fk.cxDeadKeyArray); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); @@ -314,15 +312,15 @@ TEST_F(CompilerTest, GetXStringImpl_test) { EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); fk.cxDeadKeyArray = 0; - // type=0, dk, CERR_InvalidDeadkey, bad character + // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, bad character u16cpy(str, u"dk(%)"); EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); - // type=0, dk, CERR_InvalidDeadkey, no close delimiter => NULL + // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, no close delimiter => NULL u16cpy(str, u"dk("); EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); - // type=0, dk, CERR_InvalidDeadkey, empty delimiters => empty string + // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, empty delimiters => empty string u16cpy(str, u"dk()"); EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); } From a54bbdae1b9ec78a815eae42ac5d32a2e0bbe88c Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 30 May 2024 16:32:49 +0100 Subject: [PATCH 37/53] chore(developer): add GetXStringImpl_type1 test --- .../kmcmplib/tests/gtest-compiler-test.cpp | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 17eb9c1986..232d026c70 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -270,18 +270,12 @@ TEST_F(CompilerTest, GetXStringImpl_type0_test) { KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; - // std::cerr << "debug" << std::endl; - // type=0 ('X' or 'D'), hex 32-bit u16cpy(str, u"x10330"); // Gothic A - // std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE) << std::dec << std::endl; EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); - // std::cerr << std::hex << tstr[0] << ',' << tstr[1] << std::dec << std::endl; const KMX_WCHAR tstr_GothicA[] = { 0xD800, 0xDF30, 0 }; // see UTF32ToUTF16 EXPECT_EQ(0, u16cmp(tstr_GothicA, tstr)); - // std::cerr << "end debug" << std::endl; - // type=0 ('X' or 'D'), decimal 8-bit u16cpy(str, u"d18"); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); @@ -325,6 +319,33 @@ TEST_F(CompilerTest, GetXStringImpl_type0_test) { EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); } +TEST_F(CompilerTest, GetXStringImpl_type1_test) { + KMX_WCHAR tstr[128]; + FILE_KEYBOARD fk; + KMX_WCHAR str[LINESIZE]; + KMX_WCHAR output[GLOBAL_BUFSIZE]; + PKMX_WCHAR newp = NULL; + + // std::cerr << "debug" << std::endl; + // std::cerr << "end debug" << std::endl; + // std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE) << std::dec << std::endl; + + // type=1 ('\"'), valid + u16cpy(str, u"\"abc\""); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(u"abc", tstr)); + + // type=1 ('\"'), CERR_UnterminatedString + u16cpy(str, u"\"abc"); + EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + + // type=1 ('\"'), CERR_ExtendedStringTooLong + u16cpy(str, u"\"abc\""); + EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fk, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error + + // type=1 ('\"'), CERR_ExtendedStringTooLong *** TODO *** +} + // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // KMX_DWORD process_platform(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From 5113f0d88d50f98297657e9f3d9618b5ee367e41 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 30 May 2024 16:36:11 +0100 Subject: [PATCH 38/53] chore(developer): add GetXStringImpl_type2 test --- .../kmcmplib/tests/gtest-compiler-test.cpp | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 232d026c70..89072cbec2 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -326,10 +326,6 @@ TEST_F(CompilerTest, GetXStringImpl_type1_test) { KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; - // std::cerr << "debug" << std::endl; - // std::cerr << "end debug" << std::endl; - // std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE) << std::dec << std::endl; - // type=1 ('\"'), valid u16cpy(str, u"\"abc\""); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); @@ -346,6 +342,33 @@ TEST_F(CompilerTest, GetXStringImpl_type1_test) { // type=1 ('\"'), CERR_ExtendedStringTooLong *** TODO *** } +TEST_F(CompilerTest, GetXStringImpl_type2_test) { + KMX_WCHAR tstr[128]; + FILE_KEYBOARD fk; + KMX_WCHAR str[LINESIZE]; + KMX_WCHAR output[GLOBAL_BUFSIZE]; + PKMX_WCHAR newp = NULL; + + // std::cerr << "debug" << std::endl; + // std::cerr << "end debug" << std::endl; + // std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE) << std::dec << std::endl; + + // type=2 ('\''), valid + u16cpy(str, u"\'abc\'"); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(u"abc", tstr)); + + // type=2 ('\''), CERR_UnterminatedString + u16cpy(str, u"\'abc"); + EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + + // type=2 ('\''), CERR_ExtendedStringTooLong + u16cpy(str, u"\'abc\'"); + EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fk, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error + + // type=2 ('\''), CERR_ExtendedStringTooLong *** TODO *** +} + // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // KMX_DWORD process_platform(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From 3ee8359f8f297be7bd0daf4c47ebcdbf4f6ecd7f Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 29 May 2024 17:15:11 +0200 Subject: [PATCH 39/53] refactor(web): Replace deprecated substr with slice Also add a comment to `SourcemappedWorker` explaining the difference to `DefaultWorker`. --- common/predictive-text/src/web/sourcemappedWorker.ts | 3 +++ web/src/app/webview/src/debug-main.ts | 6 +++--- web/src/app/webview/src/release-main.ts | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/common/predictive-text/src/web/sourcemappedWorker.ts b/common/predictive-text/src/web/sourcemappedWorker.ts index da7ed77eb9..18a89ab05f 100644 --- a/common/predictive-text/src/web/sourcemappedWorker.ts +++ b/common/predictive-text/src/web/sourcemappedWorker.ts @@ -2,6 +2,9 @@ import unwrap from '../unwrap.js'; import { LMLayerWorkerCode, LMLayerWorkerSourcemapComment } from "@keymanapp/lm-worker/worker-main.wrapped.js"; export default class SourcemappedWorker { + // the only difference to DefaultWorker is that this class uses + // the unminified LM* blobs + static constructInstance(): Worker { return new Worker(this.asBlobURI(LMLayerWorkerCode)); } diff --git a/web/src/app/webview/src/debug-main.ts b/web/src/app/webview/src/debug-main.ts index f8331e36de..7e4d026204 100644 --- a/web/src/app/webview/src/debug-main.ts +++ b/web/src/app/webview/src/debug-main.ts @@ -8,8 +8,8 @@ import { SourcemappedWorker } from '@keymanapp/lexical-model-layer/web' * This can only be done during load when the active script will be the * last script loaded. Otherwise the script must be identified by name. */ - var scripts = document.getElementsByTagName('script'); - var ss = scripts[scripts.length-1].src; - var sPath = ss.substr(0,ss.lastIndexOf('/')+1); +const scripts = document.getElementsByTagName('script'); +const ss = scripts[scripts.length-1].src; +const sPath = ss.slice(0,ss.lastIndexOf('/')); window['keyman'] = new KeymanEngine(SourcemappedWorker.constructInstance(), sPath); \ No newline at end of file diff --git a/web/src/app/webview/src/release-main.ts b/web/src/app/webview/src/release-main.ts index 8fba3bb293..3758b887d8 100644 --- a/web/src/app/webview/src/release-main.ts +++ b/web/src/app/webview/src/release-main.ts @@ -8,8 +8,8 @@ import { Worker } from '@keymanapp/lexical-model-layer/web' * This can only be done during load when the active script will be the * last script loaded. Otherwise the script must be identified by name. */ - var scripts = document.getElementsByTagName('script'); - var ss = scripts[scripts.length-1].src; - var sPath = ss.substr(0,ss.lastIndexOf('/')+1); +const scripts = document.getElementsByTagName('script'); +const ss = scripts[scripts.length-1].src; +const sPath = ss.slice(0,ss.lastIndexOf('/')); window['keyman'] = new KeymanEngine(Worker.constructInstance(), sPath); \ No newline at end of file From 93eabd96abea77bc91fded2f01fd2993ff30bb46 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 3 Jun 2024 12:20:02 +0200 Subject: [PATCH 40/53] refactor(web): use `substring` instead of `slice` This addresses code review comments which recommended to use `substring` as this makes it more consistent with the rest of our code base. --- web/src/app/webview/src/debug-main.ts | 2 +- web/src/app/webview/src/release-main.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/app/webview/src/debug-main.ts b/web/src/app/webview/src/debug-main.ts index 7e4d026204..02a47101a6 100644 --- a/web/src/app/webview/src/debug-main.ts +++ b/web/src/app/webview/src/debug-main.ts @@ -10,6 +10,6 @@ import { SourcemappedWorker } from '@keymanapp/lexical-model-layer/web' */ const scripts = document.getElementsByTagName('script'); const ss = scripts[scripts.length-1].src; -const sPath = ss.slice(0,ss.lastIndexOf('/')); +const sPath = ss.substring(0,ss.lastIndexOf('/')+1); window['keyman'] = new KeymanEngine(SourcemappedWorker.constructInstance(), sPath); \ No newline at end of file diff --git a/web/src/app/webview/src/release-main.ts b/web/src/app/webview/src/release-main.ts index 3758b887d8..033adc846f 100644 --- a/web/src/app/webview/src/release-main.ts +++ b/web/src/app/webview/src/release-main.ts @@ -10,6 +10,6 @@ import { Worker } from '@keymanapp/lexical-model-layer/web' */ const scripts = document.getElementsByTagName('script'); const ss = scripts[scripts.length-1].src; -const sPath = ss.slice(0,ss.lastIndexOf('/')); +const sPath = ss.substring(0,ss.lastIndexOf('/')+1); window['keyman'] = new KeymanEngine(Worker.constructInstance(), sPath); \ No newline at end of file From f8cda0ae289a0698fe6ed3f4b4fc2e797ffe0ff9 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 3 Jun 2024 11:38:43 +0100 Subject: [PATCH 41/53] chore(developer): correct TODO comment in type 1 & 2 GetXStringImpl tests --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 89072cbec2..6e3c6f2457 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -339,7 +339,7 @@ TEST_F(CompilerTest, GetXStringImpl_type1_test) { u16cpy(str, u"\"abc\""); EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fk, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - // type=1 ('\"'), CERR_ExtendedStringTooLong *** TODO *** + // type=1 ('\"'), CERR_StringInVirtualKeySection *** TODO *** } TEST_F(CompilerTest, GetXStringImpl_type2_test) { @@ -366,7 +366,7 @@ TEST_F(CompilerTest, GetXStringImpl_type2_test) { u16cpy(str, u"\'abc\'"); EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fk, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - // type=2 ('\''), CERR_ExtendedStringTooLong *** TODO *** + // type=2 ('\''), CERR_StringInVirtualKeySection *** TODO *** } // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From cb9f5fe6de6e529c66735098b95d1598af7dfc94 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 3 Jun 2024 16:30:09 +0100 Subject: [PATCH 42/53] chore(developer): fix for failing wasm build --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 6e3c6f2457..b3772dcc1d 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -148,7 +148,6 @@ TEST_F(CompilerTest, AddCompileError_test) { TEST_F(CompilerTest, ProcessBeginLine_test) { FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; - KMX_DWORD msg; // CERR_NoTokensFound str[0] = '\0'; @@ -303,7 +302,7 @@ TEST_F(CompilerTest, GetXStringImpl_type0_test) { EXPECT_EQ(0, (int)fk.cxDeadKeyArray); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_deadkey_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; - EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); + EXPECT_EQ(0, u16cmp(tstr_deadkey_valid, tstr)); fk.cxDeadKeyArray = 0; // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, bad character From 33d7dca15545efc6bed2c0ebb29e0418e5e57faa Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 6 Jun 2024 10:45:44 +0700 Subject: [PATCH 43/53] fix(developer): prevent two touch layout editors opening for the same file The keyboard editor has a complex edit state machine, which has grown a lot over time. This is a minimal patch to address one specific edge case scenario on that state machine, without any attempt to improve the state machine overall. The biggest change here is bubbling failure up to the main form so that it can destroy (aka Release, which is an asynchronous destroy) the editor window if it fails to load completely. Fixes: #11715 Fixes: KEYMAN-DEVELOPER-1JC --- developer/src/tike/child/UfrmKeymanWizard.pas | 28 +++-- developer/src/tike/main/UfrmMain.pas | 6 +- .../oskbuilder/UframeTouchLayoutBuilder.pas | 118 ++++++++++-------- 3 files changed, 89 insertions(+), 63 deletions(-) diff --git a/developer/src/tike/child/UfrmKeymanWizard.pas b/developer/src/tike/child/UfrmKeymanWizard.pas index d8a62db410..baa906e836 100644 --- a/developer/src/tike/child/UfrmKeymanWizard.pas +++ b/developer/src/tike/child/UfrmKeymanWizard.pas @@ -453,13 +453,13 @@ type procedure ConfirmSaveOfOldEditorWindows; procedure ConfirmSaveOfOldEditorWindow(FeatureID: TKeyboardParser_FeatureID; FModified: Boolean; const FOldFilename: string; DoSave: TProc; DoLoad: TProc); - procedure LoadFeature(ID: TKeyboardParser_FeatureID); + function LoadFeature(ID: TKeyboardParser_FeatureID): Boolean; function FeatureTab(kf: TKeyboardParser_FeatureID): TTabSheet; procedure InitFeatureTab(ID: TKeyboardParser_FeatureID); procedure FeatureModified(Sender: TObject); function SaveFeature(ID: TKeyboardParser_FeatureID): Boolean; procedure SelectTouchLayoutTemplate(APromptChange: Boolean); - procedure LoadTouchLayout; // I4034 + function LoadTouchLayout: Boolean; // I4034 function GetFontInfo(Index: TKeyboardFont): TKeyboardFontInfo; // I4057 procedure SetFontInfo(Index: TKeyboardFont; const Value: TKeyboardFontInfo); // I4057 @@ -1628,7 +1628,7 @@ begin FLayoutSetup := FOldLayoutSetup; end; -procedure TfrmKeymanWizard.LoadFeature(ID: TKeyboardParser_FeatureID); +function TfrmKeymanWizard.LoadFeature(ID: TKeyboardParser_FeatureID): Boolean; begin if FKeyboardParser.Features.ContainsKey(ID) then begin @@ -1651,7 +1651,8 @@ begin end; kfTouchLayout: begin - LoadTouchLayout; // I4034 + if not LoadTouchLayout then + Exit(False); end; else begin @@ -1667,6 +1668,7 @@ begin end; end; FFeature[ID].Modified := False; + Result := True; end; function TfrmKeymanWizard.SaveFeature(ID: TKeyboardParser_FeatureID): Boolean; @@ -2007,7 +2009,12 @@ begin LoadSettings; for kf in FKeyboardParser.Features.Keys do - LoadFeature(kf); + begin + if not LoadFeature(kf) then + begin + Exit(False); + end; + end; if FKeyboardParser.IsComplex then // I4557 pagesLayout.ActivePage := pageLayoutCode; @@ -3163,18 +3170,17 @@ begin FFeature[kfTouchLayout].Modified := True; end; -procedure TfrmKeymanWizard.LoadTouchLayout; // I4034 +function TfrmKeymanWizard.LoadTouchLayout: Boolean; // I4034 begin if pagesTouchLayout.ActivePage = pageTouchLayoutDesign then begin - if not frameTouchLayout.Load(FFeature[kfTouchLayout].Filename, False, False) then - begin - pagesTouchLayout.ActivePage := pageTouchLayoutCode; - frameTouchLayoutSource.LoadFromFile(FFeature[kfTouchLayout].Filename, tffUTF8); - end; + Result := frameTouchLayout.Load(FFeature[kfTouchLayout].Filename, False, False); end else + begin frameTouchLayoutSource.LoadFromFile(FFeature[kfTouchLayout].Filename, tffUTF8); + Result := True; + end; end; procedure TfrmKeymanWizard.SaveTouchLayout; // I3885 diff --git a/developer/src/tike/main/UfrmMain.pas b/developer/src/tike/main/UfrmMain.pas index 44b5873245..8fa7a45c9b 100644 --- a/developer/src/tike/main/UfrmMain.pas +++ b/developer/src/tike/main/UfrmMain.pas @@ -1477,8 +1477,12 @@ begin if n >= 0 then Result.ProjectFile := FGlobalProject.Files[n]; - (Result as frmClass).OpenFile(FFileName); LockWindowUpdate(0); + + if not (Result as frmClass).OpenFile(FFileName) then + begin + Result.Release; + end; end; procedure TfrmKeymanDeveloper.HelpTopic(s: string); diff --git a/developer/src/tike/oskbuilder/UframeTouchLayoutBuilder.pas b/developer/src/tike/oskbuilder/UframeTouchLayoutBuilder.pas index 4b0405a32f..68bff9fd60 100644 --- a/developer/src/tike/oskbuilder/UframeTouchLayoutBuilder.pas +++ b/developer/src/tike/oskbuilder/UframeTouchLayoutBuilder.pas @@ -90,7 +90,7 @@ type procedure cefCommand(Sender: TObject; const command: string; params: TStringList); procedure cefLoadEnd(Sender: TObject); - procedure RegisterSource; + procedure RegisterSources(const AState: string); procedure CharMapDragDrop(Sender, Source: TObject; X, Y: Integer); procedure CharMapDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); @@ -238,10 +238,12 @@ begin modWebHttpServer.AppSource.UnregisterSource(FFilename+'#state'); end; -procedure TframeTouchLayoutBuilder.RegisterSource; +procedure TframeTouchLayoutBuilder.RegisterSources(const AState: string); begin if FFilename <> '' then modWebHttpServer.AppSource.RegisterSource(FFilename, FSavedLayoutJS); + if (FFileName <> '') and (AState <> '') then + modWebHttpServer.AppSource.RegisterSource(FFilename + '#state', AState, True); end; procedure TframeTouchLayoutBuilder.ImportFromKVK(const KVKFileName: string); // I3945 @@ -332,71 +334,85 @@ begin end; UnregisterSources; - try - if ALoadFromString then + if ALoadFromString then + begin + FNewLayoutJS := AFilename; + FFilename := GetNextFilename; + end + else + begin + if ALoadFromTemplate or (AFileName = '') or not FileExists(AFileName) then begin - FNewLayoutJS := AFilename; + FBaseFileName := FTemplateFileName; FFilename := GetNextFilename; end else begin - if ALoadFromTemplate or (AFileName = '') or not FileExists(AFileName) then - begin - FBaseFileName := FTemplateFileName; - FFilename := GetNextFilename; - end - else - begin - FBaseFileName := AFileName; - FFilename := AFileName; - end; - - with TStringList.Create do - try - LoadFromFile(FBaseFileName, TEncoding.UTF8); - FNewLayoutJS := Text; - finally - Free; - end; + FBaseFileName := AFileName; + FFilename := AFileName; end; - FTouchLayout := TTouchLayout.Create; // I3642 + with TStringList.Create do try - if not FTouchLayout.Load(FNewLayoutJS) then + LoadFromFile(FBaseFileName, TEncoding.UTF8); + FNewLayoutJS := Text; + finally + Free; + end; + end; + + FTouchLayout := TTouchLayout.Create; // I3642 + try + if not FTouchLayout.Load(FNewLayoutJS) then + begin + FLastError := FTouchLayout.LoadError; // I4083 + FLastErrorOffset := FTouchLayout.LoadErrorOffset; // I4083 + FFilename := FLastFilename; + RegisterSources(FState); + Exit(False); + end + else + begin + if (FSavedLayoutJS <> '') and ALoadFromTemplate then begin - FLastError := FTouchLayout.LoadError; // I4083 - FLastErrorOffset := FTouchLayout.LoadErrorOffset; // I4083 - FFilename := FLastFilename; - Exit(False); + FOldLayout := TTouchLayout.Create; + try + FOldLayout.Load(FSavedLayoutJS); + if FTouchLayout.Merge(FOldLayout) + then FSavedLayoutJS := FTouchLayout.Save(False) + else FSavedLayoutJS := FNewLayoutJS; + finally + FOldLayout.Free; + end; end else - begin - if (FSavedLayoutJS <> '') and ALoadFromTemplate then - begin - FOldLayout := TTouchLayout.Create; - try - FOldLayout.Load(FSavedLayoutJS); - if FTouchLayout.Merge(FOldLayout) - then FSavedLayoutJS := FTouchLayout.Save(False) - else FSavedLayoutJS := FNewLayoutJS; - finally - FOldLayout.Free; - end; - end - else - FSavedLayoutJS := FNewLayoutJS; - end; - finally - FTouchLayout.Free; + FSavedLayoutJS := FNewLayoutJS; end; - finally - RegisterSource; - if (FFileName <> '') and (FState <> '') then - modWebHttpServer.AppSource.RegisterSource(FFilename + '#state', FState, True); + FTouchLayout.Free; end; + if (FFileName <> '') and modWebHttpServer.AppSource.IsSourceRegistered(FFileName) then + begin + // If two .kmn files are loaded which both reference the same + // .keyman-touch-layout file, it's safest to just block it. This is a rare + // scenario, as most keyboard projects have a single .kmn, and it usually + // indicates a project may be in a bit of chaos anyway. + ShowMessage( + 'The touch layout is already opened for editing in another keyboard '+ + 'editor. Please close the other keyboard editor before opening this one '+ + 'again.'); + + // We want to prevent this window unregistering the sources it doesn't own + // when it is destroyed immediately after this, which we can do by blanking + // the filename. + FFileName := ''; + Exit(False); + end; + + RegisterSources(FState); + try DoLoad; except From 1a3828d6c23b794cfb1e30efd2625c71fe8d0492 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 7 Jun 2024 14:55:51 +0700 Subject: [PATCH 44/53] feat(developer): support language reference in context help Adds support for `` in contexthelp.xml. --- developer/src/tike/xml/help/contexthelp.xml | 134 ++++++++++---------- developer/src/tike/xml/help/help.xsl | 13 ++ 2 files changed, 82 insertions(+), 65 deletions(-) diff --git a/developer/src/tike/xml/help/contexthelp.xml b/developer/src/tike/xml/help/contexthelp.xml index cd04d5746b..62bd8677ae 100644 --- a/developer/src/tike/xml/help/contexthelp.xml +++ b/developer/src/tike/xml/help/contexthelp.xml @@ -2,6 +2,10 @@ + +

(TODO: add documentation on group)

+
+

The Filter allows a user to reduce the number of characters displayed in the character map. The standard filter options used are by font name or block name.

@@ -12,63 +16,63 @@
-

The Filter allows a user to reduce the number of characters displayed in the +

The Filter allows a user to reduce the number of characters displayed in the character map. The standard filter options used are by font name or block name.

-

The filter format for a range is: [U+]XXXX-[U+]YYYY, where U+ is optional, +

The filter format for a range is: [U+]XXXX-[U+]YYYY, where U+ is optional, XXXX is the starting Unicode value and YYYY is the finishing Unicode value.

-

The filter format for a range is: [U+]XXXX-[U+]YYYY, where U+ is optional, +

The filter format for a range is: [U+]XXXX-[U+]YYYY, where U+ is optional, XXXX is the starting Unicode value and YYYY is the finishing Unicode value.

-

The filter format for a range is: [U+]XXXX-[U+]YYYY, where U+ is optional, +

The filter format for a range is: [U+]XXXX-[U+]YYYY, where U+ is optional, XXXX is the starting Unicode value and YYYY is the finishing Unicode value.

-

The Filter allows a user to reduce the number of characters displayed in the +

The Filter allows a user to reduce the number of characters displayed in the character map. The standard filter options used are by font name or block name.

-

">" placed at the start of an entry will only show characters in the currently - selected Character Map font. This is helpful when trying to determine which characters +

">" placed at the start of an entry will only show characters in the currently + selected Character Map font. This is helpful when trying to determine which characters a given font supports.



Example: >LAO



finds all characters with names starting in "LAO" in the current font

-

"<" placed at the start of an entry will search Unicode block names instead of - character names. This is helpful when searching for characters within related +

"<" placed at the start of an entry will search Unicode block names instead of + character names. This is helpful when searching for characters within related blocks



Example: <Thai



finds the Thai Unicode block

-

Using "*" in an entry serves as a wildcard for any number of places in that entry. - For example, searching for "greek*alpha" will find characters whose Unicode names begin - with the word "Greek" and contain the word "Alpha" any number of places later. - This is helpful when searching for characters that share a common element in +

Using "*" in an entry serves as a wildcard for any number of places in that entry. + For example, searching for "greek*alpha" will find characters whose Unicode names begin + with the word "Greek" and contain the word "Alpha" any number of places later. + This is helpful when searching for characters that share a common element in their names (e.g. capital).

-

Using "?" anywhere in an entry serves as a wildcard for that single place in the entry. - For example, searching for "s???e" will return both the SPACE and the SMILE characters, +

Using "?" anywhere in an entry serves as a wildcard for that single place in the entry. + For example, searching for "s???e" will return both the SPACE and the SMILE characters, among others.



Example: 1000-119F



-

finds all characters between U+1000 and U+119F (inclusive) - +

finds all characters between U+1000 and U+119F (inclusive) - the Myanmar alphabet in this case

@@ -78,7 +82,7 @@ -

"$" placed at the end of an entry will match from the end of a Unicode character name. +

"$" placed at the end of an entry will match from the end of a Unicode character name. This option works best when used with "*" or "?".



Example: LATIN * LETTER A$



finds only "a" and "A"

@@ -471,18 +475,18 @@ -

The name of the developer of the keyboard. This is either your full name or +

The name of the developer of the keyboard. This is either your full name or the organization you're creating a model for.

-

We recommend the name of the language, dialect, or community that this model is +

We recommend the name of the language, dialect, or community that this model is intended for. The name must be written in all the Latin letters or Arabic numerals.

-

Who owns the rights to this model and its data? Typically, - you can use the automatically generated default value: © 2024 Your Full Name or +

Who owns the rights to this model and its data? Typically, + you can use the automatically generated default value: © 2024 Your Full Name or Your Organization.

@@ -491,18 +495,18 @@
-

If this is the first time you've created a lexical model for you language, you should - leave the version as 1.0. Otherwise, your version number must conform to the following +

If this is the first time you've created a lexical model for you language, you should + leave the version as 1.0. Otherwise, your version number must conform to the following rules: A version string made of major revision number.minor revision number.

-

Specifies the default BCP 47 language tags which will be added to the package +

Specifies the default BCP 47 language tags which will be added to the package metadata and project metadata.

-

To add a language tag, click the Add button to bring up the “Select BCP 47 Tag” +

To add a language tag, click the Add button to bring up the “Select BCP 47 Tag” dialog box.

@@ -524,7 +528,7 @@ -

An Author ID is a unique identifier used to distinguish you from others +

An Author ID is a unique identifier used to distinguish you from others who have the same or similar names.

@@ -533,13 +537,13 @@ -

Enter a unique name of the model. You can use the name of the language, dialect, +

Enter a unique name of the model. You can use the name of the language, dialect, or community that this model is intended for.

-

Keyman automatically generates a model ID for you, given all the - information already filled out. Model ID helps Keyman sorts and organizes +

Keyman automatically generates a model ID for you, given all the + information already filled out. Model ID helps Keyman sorts and organizes different lexical models.

@@ -558,15 +562,15 @@ -

Wordlist tabs have two views: Design, and Code. Changes to one view are reflected - immedaitely in the other view. Wordlist files should be stored in UTF-8 encoding +

Wordlist tabs have two views: Design, and Code. Changes to one view are reflected + immedaitely in the other view. Wordlist files should be stored in UTF-8 encoding (preferably without BOM), and tab-separated format.

-

Every line of the tab-separated format file is shown here, and can be edited directly. - For most wordlists, it will be more effective to use an external dictionary tool, - such as SIL Fieldworks or SIL PrimerPrep to generate the wordlist from a text corpus, +

Every line of the tab-separated format file is shown here, and can be edited directly. + For most wordlists, it will be more effective to use an external dictionary tool, + such as SIL Fieldworks or SIL PrimerPrep to generate the wordlist from a text corpus, and use this tab just to preview the contents of the file.

@@ -575,24 +579,24 @@ -

The Sort by frequency button has no effect on the functioning of the wordlist, +

The Sort by frequency button has no effect on the functioning of the wordlist, but can help you, the editor, by showing more common words earlier in the list.

-

Editor windows in Keyman Developer supports standard Windows editing keystrokes. - Many file formats, including .kmn, .kps, .xml, .html, .js and .json, support syntax - highlighting. The text editor in Keyman uses the Monaco component from Visual Studio Code, +

Editor windows in Keyman Developer supports standard Windows editing keystrokes. + Many file formats, including .kmn, .kps, .xml, .html, .js and .json, support syntax + highlighting. The text editor in Keyman uses the Monaco component from Visual Studio Code, so all the functionality available in that editor is also available here.

-

Attempt to identify the fonts on your system that will support the - characters. You can quickly change fonts by clicking on a font name in the grid of +

Attempt to identify the fonts on your system that will support the + characters. You can quickly change fonts by clicking on a font name in the grid of identified fonts.

@@ -603,47 +607,47 @@ -

The message window appears at the bottom of the screen, or floating in a toolbar - window. It contains a list of error and warning messages returned from a compilation +

The message window appears at the bottom of the screen, or floating in a toolbar + window. It contains a list of error and warning messages returned from a compilation session. You can undock and dock the window by dragging its title bar.

-

The debugger input window is used for typing input to test the keyboard. - In the top half of this window, input you type while testing your keyboard will be - displayed, exactly the same as in use, with one exception: deadkeys will be shown +

The debugger input window is used for typing input to test the keyboard. + In the top half of this window, input you type while testing your keyboard will be + displayed, exactly the same as in use, with one exception: deadkeys will be shown visually with an OBJ symbol.

-

The lower half of the window shows a grid of the characters to the virtual left - of the insertion point, or the selected characters if you make a selection. Deadkeys - will be identified in the grid. The grid will show characters in right-to-left scripts - in backing store order, from left to right. If there are more characters in your text +

The lower half of the window shows a grid of the characters to the virtual left + of the insertion point, or the selected characters if you make a selection. Deadkeys + will be identified in the grid. The grid will show characters in right-to-left scripts + in backing store order, from left to right. If there are more characters in your text than can fit on the screen, then only those that fit will be shown in the grid.

-

The idea in regression testing is to record a sequence of keystrokes and the - output the keyboard produced, in order to test for the same behaviour when you +

The idea in regression testing is to record a sequence of keystrokes and the + output the keyboard produced, in order to test for the same behaviour when you make changes to the keyboard.

-

Use Start Log/Stop Log to record the input and output. You can then use Start Test - to run the test again, or go the Options menu to clear the log, or save or load a test, +

Use Start Log/Stop Log to record the input and output. You can then use Start Test + to run the test again, or go the Options menu to clear the log, or save or load a test, or use the batch mode to run several tests in a row.



-

If the output produced while running a test is different to that stored when recording it, - Keyman will halt the test on the line where the failure occurred, and activate +

If the output produced while running a test is different to that stored when recording it, + Keyman will halt the test on the line where the failure occurred, and activate Single Step mode.

-

In the Options menu, you can clear the log, save or load a test, +

In the Options menu, you can clear the log, save or load a test, or use the batch mode to run several tests in a row.

@@ -655,39 +659,39 @@ -

This window shows the current keystroke state, and the sequence of +

This window shows the current keystroke state, and the sequence of keystrokes that were typed to arrive at this state.

-

This shows the elements that make up rule currently being processed: the context, - the key, and also what the output will be. If the rule uses stores, the contents of +

This shows the elements that make up rule currently being processed: the context, + the key, and also what the output will be. If the rule uses stores, the contents of the store will be shown in the right-hand column, with the matched letter in red.

-

Here all the lines that have been processed to this point are shown in a list. - You can double-click on any entry in the list to display the line in the +

Here all the lines that have been processed to this point are shown in a list. + You can double-click on any entry in the list to display the line in the keyboard source.

-

This lists all the deadkeys that are currently in the context. - You can select one from the list to see it highlighted in the debug input box. - This information can also be seen in the character grid in the lower half of +

This lists all the deadkeys that are currently in the context. + You can select one from the list to see it highlighted in the debug input box. + This information can also be seen in the character grid in the lower half of the debugger input window.

-

The About dialog displays copyright and registration information for Keyman Developer, +

The About dialog displays copyright and registration information for Keyman Developer, and has a link to the Keyman website.

diff --git a/developer/src/tike/xml/help/help.xsl b/developer/src/tike/xml/help/help.xsl index 2416fdff16..5f1eb19fa0 100644 --- a/developer/src/tike/xml/help/help.xsl +++ b/developer/src/tike/xml/help/help.xsl @@ -53,6 +53,7 @@ +
Context help is not available for . @@ -66,6 +67,18 @@ + +
+ language/reference/ +
+ + +
+
+
- From f5a7d73c7333a5c0bac91be110392c7f54a85bca Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 7 Jun 2024 11:26:26 +0100 Subject: [PATCH 45/53] chore(developer): moved CompMsg.cpp refactor to fix #11738 --- developer/src/kmcmplib/src/CompMsg.cpp | 20 ++++++++++++++----- .../src/kmcmplib/tests/gtest-compmsg-test.cpp | 19 ------------------ developer/src/kmcmplib/tests/meson.build | 11 ---------- 3 files changed, 15 insertions(+), 35 deletions(-) delete mode 100644 developer/src/kmcmplib/tests/gtest-compmsg-test.cpp diff --git a/developer/src/kmcmplib/src/CompMsg.cpp b/developer/src/kmcmplib/src/CompMsg.cpp index 6480458fda..86a9b4d475 100644 --- a/developer/src/kmcmplib/src/CompMsg.cpp +++ b/developer/src/kmcmplib/src/CompMsg.cpp @@ -1,7 +1,11 @@ #include -#include -std::map CompilerErrorMap = { +struct CompilerError { + KMX_DWORD ErrorCode; + const KMX_CHAR* Text; + }; + +const struct CompilerError CompilerErrors[] = { { CERR_InvalidLayoutLine , "Invalid 'layout' command"}, { CERR_NoVersionLine , "No version line found for file"}, { CERR_InvalidGroupLine , "Invalid 'group' command"}, @@ -146,8 +150,14 @@ std::map CompilerErrorMap = { { CWARN_VirtualKeyInOutput , "Virtual keys are not supported in output"}, { 0, nullptr } -}; + }; -KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) { - return (KMX_CHAR*) CompilerErrorMap[code]; +KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) +{ + for(int i = 0; CompilerErrors[i].ErrorCode; i++) { + if(CompilerErrors[i].ErrorCode == code) { + return ( KMX_CHAR*) CompilerErrors[i].Text; + } + } + return nullptr; } diff --git a/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp b/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp deleted file mode 100644 index 94f0f40d8d..0000000000 --- a/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "..\..\common\include\kmn_compiler_errors.h" -#include "..\..\..\..\common\include\km_types.h" - -KMX_CHAR *GetCompilerErrorString(KMX_DWORD code); - -class CompMsgTest : public testing::Test { - protected: - CompMsgTest() {} - ~CompMsgTest() override {} - void SetUp() override {} - void TearDown() override {} -}; - -TEST_F(CompMsgTest, GetCompilerErrorString) { - EXPECT_EQ(nullptr, GetCompilerErrorString(CERR_None)); - EXPECT_EQ(nullptr, GetCompilerErrorString(0x00004FFF)); // top of range ERROR - EXPECT_EQ("Invalid 'layout' command", GetCompilerErrorString(CERR_InvalidLayoutLine)); -}; \ No newline at end of file diff --git a/developer/src/kmcmplib/tests/meson.build b/developer/src/kmcmplib/tests/meson.build index 187473796c..0d76e2deaa 100644 --- a/developer/src/kmcmplib/tests/meson.build +++ b/developer/src/kmcmplib/tests/meson.build @@ -167,14 +167,3 @@ gtestcompilertest = executable('gtest-compiler-test', 'gtest-compiler-test.cpp', ) test('gtest-compiler-test', gtestcompilertest) - -gtestcompmsgtest = executable('gtest-compmsg-test', 'gtest-compmsg-test.cpp', - cpp_args: defns + flags, - include_directories: inc, - name_suffix: name_suffix, - link_args: links + tests_links, - objects: lib.extract_all_objects(), - dependencies: [ icuuc_dep, gtest_dep, gmock_dep ], - ) - -test('gtest-compmsg-test', gtestcompmsgtest) From e3b18d380015c138b5775c35c9cb398900269de6 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 7 Jun 2024 12:09:55 +0100 Subject: [PATCH 46/53] chore(developer): add initGlobals() method --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index b3772dcc1d..02a10aa5ca 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -37,12 +37,13 @@ class CompilerTest : public testing::Test { CompilerTest() {} ~CompilerTest() override {} void SetUp() override { - kmcmp::BeginLine[BEGIN_ANSI] = -1; - kmcmp::BeginLine[BEGIN_UNICODE] = -1; - kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; - kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; + initGlobals(); } void TearDown() override { + initGlobals(); + } + + void initGlobals() { msgproc = NULL; szText_stub[0] = '\0'; kmcmp::nErrors = 0; From f4dabd1cccc633ee48f8cbb29e794799940883d0 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 7 Jun 2024 18:14:32 +0100 Subject: [PATCH 47/53] chore(developer): add fileKeyboard fixture and initFileKeyboard() method --- .../kmcmplib/tests/gtest-compiler-test.cpp | 113 +++++++++++------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 02a10aa5ca..45ce8273e0 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -34,13 +34,17 @@ extern char ErrExtraLIB[ERR_EXTRA_LIB_LEN]; class CompilerTest : public testing::Test { protected: + FILE_KEYBOARD fileKeyboard; + CompilerTest() {} ~CompilerTest() override {} void SetUp() override { initGlobals(); + initFileKeyboard(fileKeyboard); } void TearDown() override { initGlobals(); + initFileKeyboard(fileKeyboard, false); } void initGlobals() { @@ -55,6 +59,40 @@ class CompilerTest : public testing::Test { kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; } + void initFileKeyboard(FILE_KEYBOARD &fk, bool isSetUp=true) { + if (!isSetUp) { + if (fk.dpStoreArray) { delete[] fk.dpStoreArray; } + if (fk.dpGroupArray) { delete[] fk.dpGroupArray; } + if (fk.lpBitmap) { delete fk.lpBitmap; } + if (fk.dpDeadKeyArray) { delete[] fk.dpDeadKeyArray; } + if (fk.dpVKDictionary) { delete fk.dpVKDictionary; } + if (fk.extra) { delete fk.extra; } + } + fk.KeyboardID = 0; + fk.version = VERSION_90; + fk.dpStoreArray = nullptr; + fk.dpGroupArray = nullptr; + fk.cxStoreArray = 0; + fk.cxGroupArray = 0; + fk.StartGroup[0] = 0; + fk.StartGroup[1] = 0; + fk.dwHotKey = 0; + fk.szName[0] = u'\0'; + fk.szLanguageName[0] = u'\0'; + fk.szCopyright[0] = u'\0'; + fk.szMessage[0] = u'\0'; + fk.lpBitmap = nullptr; + fk.dwBitmapSize = 0; + fk.dwFlags = 0; + fk.currentGroup = 0; + fk.currentStore = 0; + fk.cxDeadKeyArray = 0; + fk.dpDeadKeyArray = nullptr; + fk.cxVKDictionary = 0; + fk.dpVKDictionary = nullptr; + fk.extra = nullptr; + } + public: static KMX_CHAR szText_stub[]; @@ -147,39 +185,38 @@ TEST_F(CompilerTest, AddCompileError_test) { }; TEST_F(CompilerTest, ProcessBeginLine_test) { - FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; // CERR_NoTokensFound str[0] = '\0'; - EXPECT_EQ(CERR_NoTokensFound, ProcessBeginLine(&fk, str)); + EXPECT_EQ(CERR_NoTokensFound, ProcessBeginLine(&fileKeyboard, str)); // CERR_InvalidToken u16cpy(str, u"abc >"); - EXPECT_EQ(CERR_InvalidToken, ProcessBeginLine(&fk, str)); + EXPECT_EQ(CERR_InvalidToken, ProcessBeginLine(&fileKeyboard, str)); // CERR_RepeatedBegin, BEGIN_UNICODE kmcmp::BeginLine[BEGIN_UNICODE] = 0; // not -1 u16cpy(str, u" unicode>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); kmcmp::BeginLine[BEGIN_UNICODE] = -1; // CERR_RepeatedBegin, BEGIN_ANSI kmcmp::BeginLine[BEGIN_ANSI] = 0; // not -1 u16cpy(str, u" ansi>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); kmcmp::BeginLine[BEGIN_ANSI] = -1; // CERR_RepeatedBegin, BEGIN_NEWCONTEXT kmcmp::BeginLine[BEGIN_NEWCONTEXT] = 0; // not -1 u16cpy(str, u" newContext>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; // CERR_RepeatedBegin, BEGIN_POSTKEYSTROKE kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = 0; // not -1 u16cpy(str, u" postKeystroke>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fk, str)); + EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; }; @@ -242,129 +279,121 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { TEST_F(CompilerTest, GetXStringImpl_test) { KMX_WCHAR tstr[128]; - FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; // CERR_BufferOverflow, max=0 - EXPECT_EQ(CERR_BufferOverflow, GetXStringImpl(tstr, &fk, str, u"", output, 0, 0, &newp, FALSE)); + EXPECT_EQ(CERR_BufferOverflow, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 0, 0, &newp, FALSE)); // CERR_None, no token str[0] = '\0'; - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // CERR_NoTokensFound, empty u16cpy(str, u""); - EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fileKeyboard, str, u"c", output, 80, 0, &newp, FALSE)); // CERR_NoTokensFound, whitespace u16cpy(str, u" "); - EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fk, str, u"c", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fileKeyboard, str, u"c", output, 80, 0, &newp, FALSE)); } TEST_F(CompilerTest, GetXStringImpl_type0_test) { KMX_WCHAR tstr[128]; - FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; // type=0 ('X' or 'D'), hex 32-bit u16cpy(str, u"x10330"); // Gothic A - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_GothicA[] = { 0xD800, 0xDF30, 0 }; // see UTF32ToUTF16 EXPECT_EQ(0, u16cmp(tstr_GothicA, tstr)); // type=0 ('X' or 'D'), decimal 8-bit u16cpy(str, u"d18"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); // type=0 ('X' or 'D'), hex capital 8-bit u16cpy(str, u"X12"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); // type=0 ('X' or 'D'), hex 32-bit, CERR_InvalidCharacter u16cpy(str, u"x110000"); - EXPECT_EQ(CERR_InvalidCharacter, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_InvalidCharacter, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // type=0 ('X' or 'D'), dk, valid u16cpy(str, u"dk(A)"); - EXPECT_EQ(0, (int)fk.cxDeadKeyArray); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_dk_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); - fk.cxDeadKeyArray = 0; + fileKeyboard.cxDeadKeyArray = 0; // type=0 ('X' or 'D'), deadkey, valid u16cpy(str, u"deadkey(A)"); - EXPECT_EQ(0, (int)fk.cxDeadKeyArray); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_deadkey_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; EXPECT_EQ(0, u16cmp(tstr_deadkey_valid, tstr)); - fk.cxDeadKeyArray = 0; + fileKeyboard.cxDeadKeyArray = 0; // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, bad character u16cpy(str, u"dk(%)"); - EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, no close delimiter => NULL u16cpy(str, u"dk("); - EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, empty delimiters => empty string u16cpy(str, u"dk()"); - EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); } TEST_F(CompilerTest, GetXStringImpl_type1_test) { KMX_WCHAR tstr[128]; - FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; // type=1 ('\"'), valid u16cpy(str, u"\"abc\""); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"abc", tstr)); // type=1 ('\"'), CERR_UnterminatedString u16cpy(str, u"\"abc"); - EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // type=1 ('\"'), CERR_ExtendedStringTooLong u16cpy(str, u"\"abc\""); - EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fk, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error + EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error // type=1 ('\"'), CERR_StringInVirtualKeySection *** TODO *** } TEST_F(CompilerTest, GetXStringImpl_type2_test) { KMX_WCHAR tstr[128]; - FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; - // std::cerr << "debug" << std::endl; - // std::cerr << "end debug" << std::endl; - // std::cerr << std::hex << GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE) << std::dec << std::endl; - // type=2 ('\''), valid u16cpy(str, u"\'abc\'"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"abc", tstr)); // type=2 ('\''), CERR_UnterminatedString u16cpy(str, u"\'abc"); - EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fk, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // type=2 ('\''), CERR_ExtendedStringTooLong u16cpy(str, u"\'abc\'"); - EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fk, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error + EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error // type=2 ('\''), CERR_StringInVirtualKeySection *** TODO *** } @@ -388,21 +417,21 @@ TEST_F(CompilerTest, GetXStringImpl_type2_test) { // KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess) TEST_F(CompilerTest, GetRHS_test) { - FILE_KEYBOARD fk; + // FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; KMX_WCHAR tstr[128]; // CERR_NoTokensFound, empty string str[0] = '\0'; - EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, tstr, 80, 0, FALSE)); + EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); // CERR_NoTokensFound, no '>' u16cpy(str, u"abc"); - EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fk, str, tstr, 80, 0, FALSE)); + EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); // CERR_None u16cpy(str, u"> nul c\n"); - EXPECT_EQ(CERR_None, GetRHS(&fk, str, tstr, 80, 0, FALSE)); + EXPECT_EQ(CERR_None, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); } // void safe_wcsncpy(PKMX_WCHAR out, PKMX_WCHAR in, int cbMax) From 2ad8a76a9d876cd61419a06309bccba92544300f Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 7 Jun 2024 19:04:26 +0100 Subject: [PATCH 48/53] chore(developer): delete commented out code --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 45ce8273e0..1af7459eb3 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -417,7 +417,6 @@ TEST_F(CompilerTest, GetXStringImpl_type2_test) { // KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess) TEST_F(CompilerTest, GetRHS_test) { - // FILE_KEYBOARD fk; KMX_WCHAR str[LINESIZE]; KMX_WCHAR tstr[128]; From 877a2072569f8c382c5f219bbcd3a20653c23fd8 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 7 Jun 2024 14:09:04 -0400 Subject: [PATCH 49/53] auto: increment master version to 18.0.52 --- HISTORY.md | 16 ++++++++++++++++ VERSION.md | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 21cceb07eb..3f6bdeda65 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,21 @@ # Keyman Version History +## 18.0.51 alpha 2024-06-07 + +* fix(web): fix osk touch-focus tracking (#11705) +* fix(web): defer keyboard activation requests made during engine initialization (#11713) +* chore(developer): add context/character-map (#11656) +* chore(developer): add context/wordlist-editor (#11658) +* chore(developer): add context/new-model-project-parameters (#11677) +* fix(common): remove allowJs from web's tsconfig.base.json (#11718) +* change(web): precompile all TS-based tests (#11723) +* chore(developer): add extra logging for assertion failure when pressing backspace in debugger (#11707) +* chore: add cherry-pick information in commit messages (#11708) +* fix(developer): handle encoding errors when loading wordlists (#11711) +* chore(ios): remove dead Swift-side keyboard gesture code (#11672) +* fix(mac): change build configuration to prevent cycle error in Xcode 15 (#11730) +* refactor(web): Replace deprecated substr with substring (#11637) + ## 18.0.50 alpha 2024-06-06 * chore(common): adds retry mechanism for build script npm ci calls (#11451) diff --git a/VERSION.md b/VERSION.md index dd6ab3716f..7f0a827856 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.51 \ No newline at end of file +18.0.52 \ No newline at end of file From c1d5d45b8fc4ae33ccc11bcf1f6700246d8e0afb Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Sat, 8 Jun 2024 12:20:58 +0100 Subject: [PATCH 50/53] chore(developer): generalise googletest line in .gitignore --- developer/src/kmcmplib/subprojects/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/kmcmplib/subprojects/.gitignore b/developer/src/kmcmplib/subprojects/.gitignore index 37346d9045..0c5134859c 100644 --- a/developer/src/kmcmplib/subprojects/.gitignore +++ b/developer/src/kmcmplib/subprojects/.gitignore @@ -2,4 +2,4 @@ /*.zip /*.tgz /packagecache -/googletest-1.14.0 +/googletest-* From cdb71f4329676f37b5a00a9aa1d3e64537ff8862 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Sat, 8 Jun 2024 12:36:11 +0100 Subject: [PATCH 51/53] chore(developer): add initFileKeyboard() method --- .../kmcmplib/tests/gtest-compiler-test.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 1af7459eb3..b0696df228 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -43,8 +43,7 @@ class CompilerTest : public testing::Test { initFileKeyboard(fileKeyboard); } void TearDown() override { - initGlobals(); - initFileKeyboard(fileKeyboard, false); + deleteFileKeyboard(fileKeyboard); } void initGlobals() { @@ -59,15 +58,7 @@ class CompilerTest : public testing::Test { kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; } - void initFileKeyboard(FILE_KEYBOARD &fk, bool isSetUp=true) { - if (!isSetUp) { - if (fk.dpStoreArray) { delete[] fk.dpStoreArray; } - if (fk.dpGroupArray) { delete[] fk.dpGroupArray; } - if (fk.lpBitmap) { delete fk.lpBitmap; } - if (fk.dpDeadKeyArray) { delete[] fk.dpDeadKeyArray; } - if (fk.dpVKDictionary) { delete fk.dpVKDictionary; } - if (fk.extra) { delete fk.extra; } - } + void initFileKeyboard(FILE_KEYBOARD &fk) { fk.KeyboardID = 0; fk.version = VERSION_90; fk.dpStoreArray = nullptr; @@ -93,6 +84,15 @@ class CompilerTest : public testing::Test { fk.extra = nullptr; } + void deleteFileKeyboard(FILE_KEYBOARD &fk) { + if (fk.dpStoreArray) { delete[] fk.dpStoreArray; } + if (fk.dpGroupArray) { delete[] fk.dpGroupArray; } + if (fk.lpBitmap) { delete fk.lpBitmap; } + if (fk.dpDeadKeyArray) { delete[] fk.dpDeadKeyArray; } + if (fk.dpVKDictionary) { delete fk.dpVKDictionary; } + if (fk.extra) { delete fk.extra; } + } + public: static KMX_CHAR szText_stub[]; From 467b768ef0ea07b195f615b5172fd8e21f72ced7 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Sat, 8 Jun 2024 12:50:50 +0100 Subject: [PATCH 52/53] chore(developer): replace type int literals in GetXStringImpl test names with char names --- .../kmcmplib/tests/gtest-compiler-test.cpp | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index b0696df228..8130e135af 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -299,33 +299,34 @@ TEST_F(CompilerTest, GetXStringImpl_test) { EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fileKeyboard, str, u"c", output, 80, 0, &newp, FALSE)); } -TEST_F(CompilerTest, GetXStringImpl_type0_test) { +// tests strings starting with 'x' or 'd' +TEST_F(CompilerTest, GetXStringImpl_type_xd_test) { KMX_WCHAR tstr[128]; KMX_WCHAR str[LINESIZE]; KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; - // type=0 ('X' or 'D'), hex 32-bit + // hex 32-bit u16cpy(str, u"x10330"); // Gothic A EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_GothicA[] = { 0xD800, 0xDF30, 0 }; // see UTF32ToUTF16 EXPECT_EQ(0, u16cmp(tstr_GothicA, tstr)); - // type=0 ('X' or 'D'), decimal 8-bit + // decimal 8-bit u16cpy(str, u"d18"); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); - // type=0 ('X' or 'D'), hex capital 8-bit + // hex capital 8-bit u16cpy(str, u"X12"); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); - // type=0 ('X' or 'D'), hex 32-bit, CERR_InvalidCharacter + // hex 32-bit, CERR_InvalidCharacter u16cpy(str, u"x110000"); EXPECT_EQ(CERR_InvalidCharacter, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // type=0 ('X' or 'D'), dk, valid + // dk, valid u16cpy(str, u"dk(A)"); EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); @@ -333,7 +334,7 @@ TEST_F(CompilerTest, GetXStringImpl_type0_test) { EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); fileKeyboard.cxDeadKeyArray = 0; - // type=0 ('X' or 'D'), deadkey, valid + // deadkey, valid u16cpy(str, u"deadkey(A)"); EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); @@ -341,61 +342,63 @@ TEST_F(CompilerTest, GetXStringImpl_type0_test) { EXPECT_EQ(0, u16cmp(tstr_deadkey_valid, tstr)); fileKeyboard.cxDeadKeyArray = 0; - // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, bad character + // dk, CERR_InvalidDeadkey, bad character u16cpy(str, u"dk(%)"); EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, no close delimiter => NULL + // dk, CERR_InvalidDeadkey, no close delimiter => NULL u16cpy(str, u"dk("); EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // type=0 ('X' or 'D'), dk, CERR_InvalidDeadkey, empty delimiters => empty string + // dk, CERR_InvalidDeadkey, empty delimiters => empty string u16cpy(str, u"dk()"); EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); } -TEST_F(CompilerTest, GetXStringImpl_type1_test) { +// tests strings starting with double quote +TEST_F(CompilerTest, GetXStringImpl_type_double_quote_test) { KMX_WCHAR tstr[128]; KMX_WCHAR str[LINESIZE]; KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; - // type=1 ('\"'), valid + // valid u16cpy(str, u"\"abc\""); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"abc", tstr)); - // type=1 ('\"'), CERR_UnterminatedString + // CERR_UnterminatedString u16cpy(str, u"\"abc"); EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // type=1 ('\"'), CERR_ExtendedStringTooLong + // CERR_ExtendedStringTooLong u16cpy(str, u"\"abc\""); EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - // type=1 ('\"'), CERR_StringInVirtualKeySection *** TODO *** + // CERR_StringInVirtualKeySection *** TODO *** } -TEST_F(CompilerTest, GetXStringImpl_type2_test) { +// tests strings starting with single quote +TEST_F(CompilerTest, GetXStringImpl_type_single_quote_test) { KMX_WCHAR tstr[128]; KMX_WCHAR str[LINESIZE]; KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = NULL; - // type=2 ('\''), valid + // valid u16cpy(str, u"\'abc\'"); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"abc", tstr)); - // type=2 ('\''), CERR_UnterminatedString + // CERR_UnterminatedString u16cpy(str, u"\'abc"); EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // type=2 ('\''), CERR_ExtendedStringTooLong + // CERR_ExtendedStringTooLong u16cpy(str, u"\'abc\'"); EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - // type=2 ('\''), CERR_StringInVirtualKeySection *** TODO *** + // CERR_StringInVirtualKeySection *** TODO *** } // KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) From f1ad109b6f3169943c8125a7386e874ee4c2549f Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Sat, 8 Jun 2024 13:09:47 +0100 Subject: [PATCH 53/53] chore(developer): add comment on deadkeys --- developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 8130e135af..7d9dd97245 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -330,7 +330,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_xd_test) { u16cpy(str, u"dk(A)"); EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - const KMX_WCHAR tstr_dk_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; + const KMX_WCHAR tstr_dk_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; // setup deadkeys EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); fileKeyboard.cxDeadKeyArray = 0; @@ -338,7 +338,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_xd_test) { u16cpy(str, u"deadkey(A)"); EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - const KMX_WCHAR tstr_deadkey_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; + const KMX_WCHAR tstr_deadkey_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; // setup deadkeys EXPECT_EQ(0, u16cmp(tstr_deadkey_valid, tstr)); fileKeyboard.cxDeadKeyArray = 0;