diff --git a/.github/multi-labeler.yml b/.github/multi-labeler.yml index ffab4f55723de9813cb2ed322f5d04be9110b138..b2e84bec1076735d09847d3b68546f5a5b13a0cc 100644 --- a/.github/multi-labeler.yml +++ b/.github/multi-labeler.yml @@ -95,3 +95,7 @@ labels: - label: 'epic-ldml' matcher: branch: '.*epic-ldml.*' # anywhere in the branch name, e.g. feat/epic-ldml/developer/... or feat/developer/foo-epic-ldml + + - label: 'epic-kmcompx' + matcher: + branch: '.*epic-kmcompx.*' diff --git a/.gitignore b/.gitignore index cb0de77c31d50942fff291e345656f81ca8ff571..0abec10c3b1651343c64920b615f5a5c236de9a6 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ /common/windows/delphi/**/*.bpl /common/windows/delphi/**/*.map /common/windows/delphi/**/*.tds +/common/windows/delphi/**/*.identcache # Temp files generated during release build /windows/src/buildtools/inst/copydebug.mak @@ -190,3 +191,10 @@ lcov.info /keyman*.buildinfo /keyman*.changes /keyman*.tar.?z + +#Sabine: +# /common/test/keyboards/invalid/source/*.kmx +# /developer/src/test/auto/kmcomp/*.kmn +# /developer/src/test/auto/kmcomp/*.kvk +# /developer/src/test/auto/kmcomp/*.kvk* +# /developer/src/test/auto/kmcomp/*.txt diff --git a/HISTORY.md b/HISTORY.md index 2ec2227e8be012bd7e45f9f3d4ddc1165a56e5b7..285d9fa017f7ea5bc389a3f04623c726cd83efd6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,27 @@ # Keyman Version History +## 17.0.85 alpha 2023-04-11 + +* chore(developer): AddWarning and SetError cleanup (#8571) +* fix(developer): add DRY_RUN variable to build.sh (#8576) +* fix(ios): fixes xcode-triggered debug, run builds (#8575) + +## 17.0.84 alpha 2023-04-10 + +* epic: kmcompx - kmcmpdll cross-platform compiler (#7330) +* chore(android): Update projects to use Java 11 (#8543) +* docs: clarify dependency meanings in build-utils (#8567) +* fix(mac): fix corrupt installer (#8565) + +## 17.0.83 alpha 2023-04-05 + +* fix(windows): use right instead of left alignment for popup buttons (#8561) + +## 17.0.82 alpha 2023-03-31 + +* feat(developer): support jis and abnt2 (#8513) +* revert: #8549 "chore(web): merge master into feature-esmodule-web-engine (A17S9 end) " (#8553) + ## 17.0.81 alpha 2023-03-30 * feat(windows): simple text editor using Edit Control (#8391) diff --git a/VERSION.md b/VERSION.md index c78cc99cd538c9b0a2adfd50405686baece32a48..df6d3f85cbd1b8464dc68d920fd51e86d7bd1ff2 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.82 \ No newline at end of file +17.0.86 \ No newline at end of file diff --git a/android/KMAPro/build.gradle b/android/KMAPro/build.gradle index f77d9cc534b59115cddf2144cdd53847806f1a5d..7e49d3dc01819159a066fe7c5b4450a667867599 100644 --- a/android/KMAPro/build.gradle +++ b/android/KMAPro/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.4.0' // sentry-android-gradle-plugin 2.1.5+ requires AGP 7.0 classpath 'io.sentry:sentry-android-gradle-plugin:2.1.2' classpath 'name.remal:gradle-plugins:1.5.0' diff --git a/android/KMAPro/build.sh b/android/KMAPro/build.sh index 46a4676e2faaec20d20e8f8305a766f5256c3d81..192e3211187130db205b09b1ba36d0f63ebaeab5 100755 --- a/android/KMAPro/build.sh +++ b/android/KMAPro/build.sh @@ -80,9 +80,6 @@ fi if builder_start_action configure; then - # Copy Keyman Engine for Android - cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/${CONFIG}/keyman-engine.aar" "$KEYMAN_ROOT/android/KMAPro/kMAPro/libs/keyman-engine.aar" - KEYBOARD_PACKAGE_ID="sil_euro_latin" KEYBOARDS_TARGET="$KEYMAN_ROOT/android/KMAPro/kMAPro/src/main/assets/${KEYBOARD_PACKAGE_ID}.kmp" MODEL_PACKAGE_ID="nrc.en.mtnt" @@ -96,6 +93,9 @@ fi if builder_start_action build; then + # Copy Keyman Engine for Android + cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar" "$KEYMAN_ROOT/android/KMAPro/kMAPro/libs/keyman-engine.aar" + # Convert markdown to html for offline help build_help_html android KMAPro/kMAPro/src/main/assets/info diff --git a/android/KMAPro/gradle/wrapper/gradle-wrapper.properties b/android/KMAPro/gradle/wrapper/gradle-wrapper.properties index 41dfb87909a877d96c3af4adccce4c7a301b55a2..ae04661ee733431762e7ccf8ab9b7409ed44960c 100644 --- a/android/KMAPro/gradle/wrapper/gradle-wrapper.properties +++ b/android/KMAPro/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android/KMAPro/kMAPro/build.gradle b/android/KMAPro/kMAPro/build.gradle index df38b2ade8ac64bf87a2ad22bb27ddc90ef6ee5d..c6b4774edc73ba2d3612500399389ced632c2666 100644 --- a/android/KMAPro/kMAPro/build.gradle +++ b/android/KMAPro/kMAPro/build.gradle @@ -2,7 +2,7 @@ plugins { id 'com.android.application' id 'io.sentry.android.gradle' // https://github.com/Triple-T/gradle-play-publisher/issues/947#issuecomment-843634852 - id 'com.github.triplet.play' version '3.7.0-agp4.2' apply false + id 'com.github.triplet.play' version '3.8.1' apply false id 'name.remal.default-plugins' } @@ -16,10 +16,6 @@ android { aaptOptions { noCompress "kmp" } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } defaultConfig { applicationId "com.tavultesoft.kmapro" diff --git a/android/KMEA/app/build.gradle b/android/KMEA/app/build.gradle index 4b4da18754f130bca6dce5112e293baac545375a..2f2e969a1fc72e478134578ca4a60be04b3d6bb8 100644 --- a/android/KMEA/app/build.gradle +++ b/android/KMEA/app/build.gradle @@ -16,6 +16,9 @@ android { // VERSION_CODE and VERSION_NAME from version.gradle but Gradle removes them for libraries buildConfigField "String", "KEYMAN_ENGINE_VERSION_NAME", "\""+VERSION_NAME+"\"" buildConfigField "String", "VERSION_ENVIRONMENT", "\""+VERSION_ENVIRONMENT+"\"" + + // Sepcify library filename keyman-engine-$CONFIG.aar + setProperty("archivesBaseName", "keyman-engine") } buildTypes { @@ -25,13 +28,6 @@ android { } } - // Sepcify library filename $CONFIG/keyman-engine.aar - libraryVariants.all { variant -> - variant.outputs.all { - outputFileName = "${variant.buildType.name}/keyman-engine.aar" - } - } - // TODO: Remove ResourceType when SDK > 17 lintOptions { disable 'ImpliedQuantity', 'MissingQuantity', 'MissingTranslation', 'ResourceType' diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index 877d297a4ddeffae0f489f9140ea106c1659044c..17301d96e57febdde508229d35a8e4a7acdb7366 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -784,7 +784,7 @@ public final class KMManager { * @param permission - The manifest permission to query * @return boolean - true if the manifest permission is granted */ - protected static boolean hasPermission(Context context, String permission) { + public static boolean hasPermission(Context context, String permission) { // API to check permission depends on Android SDK level if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return (context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED); diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java index 0e1db6847fb9b586325738dd37efd760bc5b700d..1111d92978b25ce92e4253352d6c82b45554d103 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/logic/ResourcesUpdateTool.java @@ -436,7 +436,11 @@ public class ResourcesUpdateTool implements KeyboardEventHandler.OnKeyboardDownl .setAutoCancel(true) .setContentIntent(startUpdateIntent); - notificationManager.notify(notification_id,builder.build()); + try { + notificationManager.notify(notification_id, builder.build()); + } catch (SecurityException e) { + KMLog.LogException(TAG, "Security permission POST_NOTIFICATIONS denied", e); + } } private boolean isContextAvailable() { diff --git a/android/KMEA/app/src/test/resources/com/tavultesoft/kmea/robolectric.properties b/android/KMEA/app/src/test/resources/com/tavultesoft/kmea/robolectric.properties index 1c3d9c523c48b87c383ca4417adbcf1a28494fa8..480ab323eae4117794ffd24d9816472a8a318997 100644 --- a/android/KMEA/app/src/test/resources/com/tavultesoft/kmea/robolectric.properties +++ b/android/KMEA/app/src/test/resources/com/tavultesoft/kmea/robolectric.properties @@ -1,3 +1,2 @@ -#Android SDK 29 requires java 9. -#To execute the tests on during the automatic build process, we need to force robolectric to use an older sdk version for test -sdk=28 \ No newline at end of file +#Android SDK to use for tests. +sdk=33 \ No newline at end of file diff --git a/android/KMEA/build.gradle b/android/KMEA/build.gradle index 55a31cb9af6d4dacfab68362ebb7ed65074c9eb1..8e6b39bd3e3cb4051878835e18e2031df016a423 100644 --- a/android/KMEA/build.gradle +++ b/android/KMEA/build.gradle @@ -5,9 +5,7 @@ buildscript { mavenCentral() } dependencies { - // Gradle plugin 7.3.0+ requires JDK 11 - // https://developer.android.com/studio/releases/gradle-plugin#compatibility-7-3-0 - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.4.0' // io.sentry:sentry-android-gradle-plugin not available for library project classpath 'io.sentry:sentry-android:6.9.2' classpath 'name.remal:gradle-plugins:1.5.0' diff --git a/android/KMEA/build.sh b/android/KMEA/build.sh index cc38865bf4ec00c633d140d3b8f7c512ed9d361f..61ace2d49975662c74d28b5c778b6352cfb94dc4 100755 --- a/android/KMEA/build.sh +++ b/android/KMEA/build.sh @@ -50,8 +50,7 @@ if builder_is_debug_build; then fi builder_describe_outputs \ - configure:engine /android/KMEA/app/src/main/assets/keymanweb-webview.js \ - build:engine /android/KMEA/app/build/outputs/aar/${CONFIG}/keyman-engine.aar + build:engine /android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar #### Build @@ -73,6 +72,14 @@ fi if builder_start_action configure:engine; then + builder_finish_action success configure:engine +fi + +# Destinations that will need the keymanweb artifacts + + +if builder_start_action build:engine; then + # Copy KeymanWeb artifacts echo "Copying Keyman Web artifacts" cp "$KEYMAN_WEB_ROOT/build/app/webview/$CONFIG/index.js" "$ENGINE_ASSETS/keymanweb-webview.js" @@ -88,14 +95,6 @@ if builder_start_action configure:engine; then echo "Copying es6-shim polyfill" cp "$KEYMAN_ROOT/node_modules/es6-shim/es6-shim.min.js" "$ENGINE_ASSETS/es6-shim.min.js" - builder_finish_action success configure:engine -fi - -# Destinations that will need the keymanweb artifacts - - -if builder_start_action build:engine; then - echo "BUILD_FLAGS $BUILD_FLAGS" # Build without test ./gradlew $DAEMON_FLAG clean $BUILD_FLAGS diff --git a/android/KMEA/gradle/wrapper/gradle-wrapper.properties b/android/KMEA/gradle/wrapper/gradle-wrapper.properties index 41dfb87909a877d96c3af4adccce4c7a301b55a2..ae04661ee733431762e7ccf8ab9b7409ed44960c 100644 --- a/android/KMEA/gradle/wrapper/gradle-wrapper.properties +++ b/android/KMEA/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android/README.md b/android/README.md index ffdbb4a015c1f9f540f5710b5cb524ac29ad4484..bd60a07bb81c51534e81d48a255687604989aca7 100644 --- a/android/README.md +++ b/android/README.md @@ -119,10 +119,6 @@ android { aaptOptions { noCompress "kmp" } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } ``` 5. After the `android {}` object, include the following: ````gradle diff --git a/android/Samples/KMSample1/app/build.gradle b/android/Samples/KMSample1/app/build.gradle index 23dbaf892b0ccf13697e9745cf0b5a55727056c7..497673f3004dc03e4ab129a2238ca253a1398cc3 100644 --- a/android/Samples/KMSample1/app/build.gradle +++ b/android/Samples/KMSample1/app/build.gradle @@ -9,10 +9,6 @@ android { aaptOptions { noCompress "kmp" } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } defaultConfig { applicationId "com.keyman.kmsample1" diff --git a/android/Samples/KMSample1/build.gradle b/android/Samples/KMSample1/build.gradle index 2210ec42b7d0f15ea0dd0c6e2f2342eab8e50b1a..d764f927ded6a435fd5d35c4ffbc98814fb84e60 100644 --- a/android/Samples/KMSample1/build.gradle +++ b/android/Samples/KMSample1/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.4.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/android/Samples/KMSample1/build.sh b/android/Samples/KMSample1/build.sh index 35f006de66678f333ca6273600ffc8cef8695c26..12c72c78b9dfac285001ebd8ada0b3e72ceeb712 100755 --- a/android/Samples/KMSample1/build.sh +++ b/android/Samples/KMSample1/build.sh @@ -66,14 +66,16 @@ if builder_start_action clean:app; then fi if builder_start_action configure:app; then - # Copy Keyman Engine for Android - cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/${CONFIG}/keyman-engine.aar" "$KEYMAN_ROOT/android/Samples/KMSample1/app/libs/keyman-engine.aar" builder_finish_action success configure:app fi # Building KMSample1 if builder_start_action build:app; then + + # Copy Keyman Engine for Android + cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar" "$KEYMAN_ROOT/android/Samples/KMSample1/app/libs/keyman-engine.aar" + ./gradlew clean $SAMPLE_FLAGS builder_finish_action success build:app diff --git a/android/Samples/KMSample1/gradle/wrapper/gradle-wrapper.properties b/android/Samples/KMSample1/gradle/wrapper/gradle-wrapper.properties index d7e11852f714a63f69265d8a422001803682295a..5da5e9c373610bc58906b4d5f9a67d4e95836664 100644 --- a/android/Samples/KMSample1/gradle/wrapper/gradle-wrapper.properties +++ b/android/Samples/KMSample1/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip diff --git a/android/Samples/KMSample2/app/build.gradle b/android/Samples/KMSample2/app/build.gradle index 856bcb7bf65f6c50cd157f1914306e811db62e6d..547050d9ce467d35db2dedf81c1cc03b85941a0d 100644 --- a/android/Samples/KMSample2/app/build.gradle +++ b/android/Samples/KMSample2/app/build.gradle @@ -9,10 +9,6 @@ android { aaptOptions { noCompress "kmp" } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } defaultConfig { applicationId "com.keyman.kmsample2" diff --git a/android/Samples/KMSample2/build.sh b/android/Samples/KMSample2/build.sh index d49ad747490f0734e9db3764c0452beb10e722db..100669c251197c6233bbabb966e7102081375607 100755 --- a/android/Samples/KMSample2/build.sh +++ b/android/Samples/KMSample2/build.sh @@ -66,14 +66,15 @@ if builder_start_action clean:app; then fi if builder_start_action configure:app; then - # Copy Keyman Engine for Android - cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/${CONFIG}/keyman-engine.aar" "$KEYMAN_ROOT/android/Samples/KMSample2/app/libs/keyman-engine.aar" builder_finish_action success configure:app fi # Building KMSample2 if builder_start_action build:app; then + # Copy Keyman Engine for Android + cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar" "$KEYMAN_ROOT/android/Samples/KMSample2/app/libs/keyman-engine.aar" + ./gradlew clean $SAMPLE_FLAGS builder_finish_action success build:app diff --git a/android/Samples/KMSample2/gradle/wrapper/gradle-wrapper.properties b/android/Samples/KMSample2/gradle/wrapper/gradle-wrapper.properties index 012002768e8c60441e003328d9f8d630d6975ba0..820c8f35ed014f6a52d12616bc750cd3b426fbf5 100644 --- a/android/Samples/KMSample2/gradle/wrapper/gradle-wrapper.properties +++ b/android/Samples/KMSample2/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip diff --git a/android/Tests/KeyboardHarness/build.gradle b/android/Tests/KeyboardHarness/build.gradle index 1f5bd9cd316eb6741067c4c9daf6d1d54bc7f18f..ce0b936509fa8471c2c10485ce680363e558dd83 100644 --- a/android/Tests/KeyboardHarness/build.gradle +++ b/android/Tests/KeyboardHarness/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.4.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/android/Tests/KeyboardHarness/build.sh b/android/Tests/KeyboardHarness/build.sh index c534483e598e1ad3bd6efb0716889f086aa5ba9f..f1b3f5c0979ba041cfb8a070002e1c4d40b0ed0e 100755 --- a/android/Tests/KeyboardHarness/build.sh +++ b/android/Tests/KeyboardHarness/build.sh @@ -74,8 +74,6 @@ if builder_start_action clean:app; then fi if builder_start_action configure:app; then - # Copy Keyman Engine for Android - cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/${CONFIG}/keyman-engine.aar" "$KEYMAN_ROOT/android/Tests/KeyboardHarness/app/libs/keyman-engine.aar" builder_finish_action success configure:app fi @@ -83,6 +81,9 @@ fi # Building KeyboardHarness if builder_start_action build:app; then + # Copy Keyman Engine for Android + cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar" "$KEYMAN_ROOT/android/Tests/KeyboardHarness/app/libs/keyman-engine.aar" + echo "BUILD_FLAGS: $BUILD_FLAGS" ./gradlew clean $BUILD_FLAGS builder_finish_action success build:app diff --git a/android/Tests/KeyboardHarness/gradle/wrapper/gradle-wrapper.properties b/android/Tests/KeyboardHarness/gradle/wrapper/gradle-wrapper.properties index ab00602c5fe8c5846bf379afa839e263d4d138e2..207d03ae62bf2c1f06ae89a96a8c3d08f47de214 100644 --- a/android/Tests/KeyboardHarness/gradle/wrapper/gradle-wrapper.properties +++ b/android/Tests/KeyboardHarness/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip diff --git a/android/Tests/keycode/build.gradle b/android/Tests/keycode/build.gradle index de09b28e088f64260f5a826d2d180f7802fb3756..e67b0d3c17914f53a924452bafbd4b37d419287f 100644 --- a/android/Tests/keycode/build.gradle +++ b/android/Tests/keycode/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.4.0' // NOTE: Do not place your application dependencies here; they belong diff --git a/android/Tests/keycode/gradle/wrapper/gradle-wrapper.properties b/android/Tests/keycode/gradle/wrapper/gradle-wrapper.properties index b1159fc54f39b3b208f767fd65a460b6016e04ad..8fad3f5a98bf4a104de5df8345c1f59f984cba8a 100644 --- a/android/Tests/keycode/gradle/wrapper/gradle-wrapper.properties +++ b/android/Tests/keycode/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android/build-publish.sh b/android/build-publish.sh index 5aea4a867da3152652e16c5ec0a93783b8f18a3e..7e52edad9278ca6f4b00500d370057a7aef70ca9 100755 --- a/android/build-publish.sh +++ b/android/build-publish.sh @@ -57,6 +57,9 @@ while [[ $# -gt 0 ]] ; do shift # past argument done +# Override JAVA_HOME to OpenJDK 11 +set_java_home + echo echo "NO_DAEMON: $NO_DAEMON" echo "DO_KMAPRO: $DO_KMAPRO" diff --git a/android/build.sh b/android/build.sh index eae19089e5ec03724eaf15bb2ec78d895149ea2e..b22d8887f1ed535cbb952254350bff9b798b97e0 100755 --- a/android/build.sh +++ b/android/build.sh @@ -37,6 +37,9 @@ builder_describe \ builder_parse "$@" +# Override JAVA_HOME to OpenJDK 11 +set_java_home + # This script also responsible for cleaning up /android/upload builder_run_child_actions clean diff --git a/common/include/.gitignore b/common/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..39eb38049fb9d488df0054a682651b27f6aeac5d --- /dev/null +++ b/common/include/.gitignore @@ -0,0 +1,2 @@ +keymanversion_build.h +.keymanversion_build.configured \ No newline at end of file diff --git a/common/include/build.sh b/common/include/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..43d8c51a510fc5aa9ac622f9db6a1696b7196ee0 --- /dev/null +++ b/common/include/build.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Creates keymanversion_build.h +# + +# Exit on command failure and when using unset variables: +set -eu + +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../resources/build/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +cd "$THIS_SCRIPT_PATH" + +builder_describe "Build keymanversion_build.h" configure build clean + +builder_describe_outputs \ + configure /common/include/.keymanversion_build.configured \ + build /common/include/keymanversion_build.h + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +if builder_start_action clean; then + rm -f keymanversion_build.h .keymanversion_build.configured + builder_finish_action success clean +fi + +if builder_start_action configure; then + # no-op, keeping 'configure' for deps + touch .keymanversion_build.configured + builder_finish_action success configure +fi + +if builder_start_action build; then + replaceVersionStrings_Mkver keymanversion_build.in keymanversion_build.h + builder_finish_action success build +fi diff --git a/common/windows/cpp/include/keymanversion_build.in b/common/include/keymanversion_build.in similarity index 94% rename from common/windows/cpp/include/keymanversion_build.in rename to common/include/keymanversion_build.in index a6a9ee010b736e97b86b129326aa30bcba05f1f8..80724f103b5d16969a0f90f0a3a72e51a1582c1d 100644 --- a/common/windows/cpp/include/keymanversion_build.in +++ b/common/include/keymanversion_build.in @@ -1,6 +1,6 @@ #pragma once -// This file is transformed from keymanversion_build.in to keymanversion_build.h by mkver +// This file is transformed from keymanversion_build.in to keymanversion_build.h by /common/include/build.sh // Legacy version number defines #define KEYMANVERSION "$RELEASE" @@ -12,6 +12,7 @@ #define KEYMAN_VersionWin "$VersionWin" #define KEYMAN_VersionWin_W L"$VersionWin" +#define KEYMAN_VersionWin_W16 u"$VersionWin" #define KEYMAN_VersionRelease "$VersionRelease" #define KEYMAN_VersionRelease_W L"$VersionRelease" diff --git a/common/include/km_types.h b/common/include/km_types.h index bf25b354b5123338f2ec6d8fc97a4661d1df11dd..d81f2672384c5bd9e091d109338e53a1e57e8b3a 100644 --- a/common/include/km_types.h +++ b/common/include/km_types.h @@ -1,4 +1,5 @@ #pragma once +#include #include @@ -21,30 +22,31 @@ #define KMX_64BIT #endif -typedef uint32_t KMX_DWORD; -typedef int32_t KMX_BOOL; -typedef uint8_t KMX_BYTE; -typedef uint16_t KMX_WORD; +typedef uint32_t KMX_DWORD; +typedef int32_t KMX_BOOL; +typedef uint8_t KMX_BYTE; +typedef uint16_t KMX_WORD; #if defined(__cplusplus) typedef char16_t km_kbp_cp; typedef char32_t km_kbp_usv; #else -typedef uint16_t km_kbp_cp; // code point -typedef uint32_t km_kbp_usv; // Unicode Scalar Value +typedef uint16_t km_kbp_cp; // code point +typedef uint32_t km_kbp_usv; // Unicode Scalar Value #endif -typedef km_kbp_cp KMX_WCHAR; // wc, 16-bit UNICODE character -typedef KMX_WCHAR *PKMX_WCHAR; +typedef km_kbp_cp KMX_WCHAR; // wc, 16-bit UNICODE character +typedef KMX_WCHAR* PKMX_WCHAR; -typedef char KMX_CHAR; -typedef KMX_CHAR *PKMX_CHAR; +typedef char KMX_CHAR; +typedef char* PKMX_STR; +typedef KMX_CHAR* PKMX_CHAR; -typedef uint32_t KMX_UINT; +typedef uint32_t KMX_UINT; -typedef KMX_BYTE *PKMX_BYTE; -typedef KMX_WORD *PKMX_WORD; -typedef KMX_DWORD *PKMX_DWORD; +typedef KMX_BYTE* PKMX_BYTE; +typedef KMX_WORD* PKMX_WORD; +typedef KMX_DWORD* PKMX_DWORD; #ifndef FALSE #define FALSE 0 diff --git a/common/include/kmx_file.h b/common/include/kmx_file.h index 4519e0ccef3117ad3b0c52e6845f6c7e1f8190aa..998c97800728e600e8a0be0e2a931e9544438118 100644 --- a/common/include/kmx_file.h +++ b/common/include/kmx_file.h @@ -64,6 +64,8 @@ namespace kmx { // Different begin types #define BEGIN_ANSI 0 #define BEGIN_UNICODE 1 +#define BEGIN_NEWCONTEXT 2 +#define BEGIN_POSTKEYSTROKE 3 #define TSS_NONE 0 #define TSS_BITMAP 1 @@ -302,6 +304,7 @@ struct COMP_STORE { struct COMP_KEY { KMX_WORD Key; + KMX_WORD _reserved; KMX_DWORD Line; KMX_DWORD ShiftFlags; KMX_DWORD dpOutput; diff --git a/core/tests/unit/test_assert.h b/common/include/test_assert.h similarity index 100% rename from core/tests/unit/test_assert.h rename to common/include/test_assert.h diff --git a/core/tests/unit/test_color.h b/common/include/test_color.h similarity index 100% rename from core/tests/unit/test_color.h rename to common/include/test_color.h diff --git a/common/test/keyboards/baseline/README.md b/common/test/keyboards/baseline/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cede107085160bc4cfbf00f9bba32a969c517d8c --- /dev/null +++ b/common/test/keyboards/baseline/README.md @@ -0,0 +1,24 @@ +# Keyboard baseline fixtures + +This folder contains a set of keyboards that are used by multiple projects to +verify behaviour, both for compilation, and for runtime tests. + +The following projects are known to use these keyboards: +* core -- .kmn files only, compiled with kmc during tests +* developer/kmcmplib -- .kmn files, compiled for tests, and .kmx as reference +* linux -- .kmn files for test steps only, .kmx files + +The .kmx files were built with kmcomp, not kmc, in order to ensure that +developer/kmcmplib gets a valid baseline reference. + +Once kmc is stable, it is possible that we will be able to use the kmc npm +module to build .kmx for all projects that need them. + +## Build parameters + +Keyboards were built with debug information and no compiler version embedded, +with kmcomp 16.0.138: + +```bat +for %d in (*.kmn) do kmcomp -no-compiler-version -d %d +``` diff --git a/common/test/keyboards/baseline/baseline.kpj b/common/test/keyboards/baseline/baseline.kpj new file mode 100644 index 0000000000000000000000000000000000000000..b98e7519fda1980e86dbcf6748de7b25dd576ce8 --- /dev/null +++ b/common/test/keyboards/baseline/baseline.kpj @@ -0,0 +1,327 @@ + + + + $PROJECTPATH\build + False + False + True + keyboard + + + + id_k_000___null_keyboard + k_000___null_keyboard.kmn + k_000___null_keyboard.kmn + 1.0 + .kmn + + + id_k_001___basic_input_unicodei + k_001___basic_input_unicodei.kmn + k_001___basic_input_unicodei.kmn + 1.0 + .kmn + + + id_k_002___basic_input_unicode + k_002___basic_input_unicode.kmn + k_002___basic_input_unicode.kmn + 1.0 + .kmn + + + id_k_003___nul + k_003___nul.kmn + k_003___nul.kmn + 1.0 + .kmn + + + id_k_004___basic_input__shift_2_ + k_004___basic_input__shift_2_.kmn + k_004___basic_input__shift_2_.kmn + 1.0 + .kmn + + + id_k_005___nul_with_initial_context + k_005___nul_with_initial_context.kmn + k_005___nul_with_initial_context.kmn + 1.0 + .kmn + + + id_k_006___vkey_input__shift_ctrl_ + k_006___vkey_input__shift_ctrl_.kmn + k_006___vkey_input__shift_ctrl_.kmn + 1.0 + .kmn + + + id_k_007___vkey_input__ctrl_alt_ + k_007___vkey_input__ctrl_alt_.kmn + k_007___vkey_input__ctrl_alt_.kmn + 1.0 + .kmn + + + id_k_008___vkey_input__ctrl_alt_2_ + k_008___vkey_input__ctrl_alt_2_.kmn + k_008___vkey_input__ctrl_alt_2_.kmn + 1.0 + .kmn + + + id_k_012___ralt + k_012___ralt.kmn + k_012___ralt.kmn + 1.0 + .kmn + + + id_k_013___deadkeys + k_013___deadkeys.kmn + k_013___deadkeys.kmn + 1.0 + .kmn + + + id_k_014___groups_and_virtual_keys + k_014___groups_and_virtual_keys.kmn + k_014___groups_and_virtual_keys.kmn + 1.0 + .kmn + + + id_k_015___ralt_2 + k_015___ralt_2.kmn + k_015___ralt_2.kmn + 1.0 + .kmn + + + id_k_017___space_mnemonic_kbd + k_017___space_mnemonic_kbd.kmn + k_017___space_mnemonic_kbd.kmn + 1.0 + .kmn + + + id_k_018___nul_testing + k_018___nul_testing.kmn + k_018___nul_testing.kmn + 1.0 + .kmn + + + id_k_019___multiple_deadkeys + k_019___multiple_deadkeys.kmn + k_019___multiple_deadkeys.kmn + 1.0 + .kmn + + + id_k_020___deadkeys_and_backspace + k_020___deadkeys_and_backspace.kmn + k_020___deadkeys_and_backspace.kmn + 1.0 + .kmn + + + id_k_021___options + k_021___options.kmn + k_021___options.kmn + 1.0 + .kmn + + + id_k_022___options_with_preset + k_022___options_with_preset.kmn + k_022___options_with_preset.kmn + 1.0 + .kmn + + + id_k_023___options_with_save + k_023___options_with_save.kmn + k_023___options_with_save.kmn + 1.0 + .kmn + + + id_k_024___options_with_save_and_preset + k_024___options_with_save_and_preset.kmn + k_024___options_with_save_and_preset.kmn + 1.0 + .kmn + + + id_k_025___options_with_reset + k_025___options_with_reset.kmn + k_025___options_with_reset.kmn + 1.0 + .kmn + + + id_k_026___system_stores + k_026___system_stores.kmn + k_026___system_stores.kmn + 1.0 + .kmn + + + id_k_027___system_stores_2 + k_027___system_stores_2.kmn + k_027___system_stores_2.kmn + 1.0 + .kmn + + + id_k_028___smp + k_028___smp.kmn + k_028___smp.kmn + 1.0 + .kmn + + + id_k_029___beep + k_029___beep.kmn + k_029___beep.kmn + 1.0 + .kmn + + + id_k_030___multiple_groups + k_030___multiple_groups.kmn + k_030___multiple_groups.kmn + 1.0 + .kmn + + + id_k_031___caps_lock + k_031___caps_lock.kmn + k_031___caps_lock.kmn + 1.0 + .kmn + + + id_k_032___caps_control + k_032___caps_control.kmn + k_032___caps_control.kmn + 1.0 + .kmn + + + id_k_033___caps_always_off + k_033___caps_always_off.kmn + k_033___caps_always_off.kmn + 1.0 + .kmn + + + id_k_034___options_double_set_reset + k_034___options_double_set_reset.kmn + k_034___options_double_set_reset.kmn + 1.0 + .kmn + + + id_k_035___options_double_set_staged + k_035___options_double_set_staged.kmn + k_035___options_double_set_staged.kmn + 1.0 + .kmn + + + id_k_036___options___double_reset_staged + k_036___options___double_reset_staged.kmn + k_036___options___double_reset_staged.kmn + 1.0 + .kmn + + + id_k_037___options___double_reset + k_037___options___double_reset.kmn + k_037___options___double_reset.kmn + 1.0 + .kmn + + + id_k_038___punctkeys + k_038___punctkeys.kmn + k_038___punctkeys.kmn + 1.0 + .kmn + + + id_k_039___generic_ctrlalt + k_039___generic_ctrlalt.kmn + k_039___generic_ctrlalt.kmn + 1.0 + .kmn + + + id_k_040___long_context + k_040___long_context.kmn + k_040___long_context.kmn + 1.0 + .kmn + + + id_k_041___long_context_and_deadkeys + k_041___long_context_and_deadkeys.kmn + k_041___long_context_and_deadkeys.kmn + 1.0 + .kmn + + + id_k_042___long_context_and_split_deadkeys + k_042___long_context_and_split_deadkeys.kmn + k_042___long_context_and_split_deadkeys.kmn + 1.0 + .kmn + + + id_k_043___output_and_keystroke + k_043___output_and_keystroke.kmn + k_043___output_and_keystroke.kmn + 1.0 + .kmn + + + id_k_044___if_and_context + k_044___if_and_context.kmn + k_044___if_and_context.kmn + 1.0 + .kmn + + + id_k_045___deadkey_and_context + k_045___deadkey_and_context.kmn + k_045___deadkey_and_context.kmn + 1.0 + .kmn + + + id_k_046___deadkey_and_contextex + k_046___deadkey_and_contextex.kmn + k_046___deadkey_and_contextex.kmn + 1.0 + .kmn + + + id_k_047___caps_always_off_initially_on + k_047___caps_always_off_initially_on.kmn + k_047___caps_always_off_initially_on.kmn + 1.0 + .kmn + + + id_k_048___modifier_keys_keep_context + k_048___modifier_keys_keep_context.kmn + k_048___modifier_keys_keep_context.kmn + 1.0 + .kmn + + + diff --git a/common/test/keyboards/baseline/k_000___null_keyboard.kmn b/common/test/keyboards/baseline/k_000___null_keyboard.kmn new file mode 100644 index 0000000000000000000000000000000000000000..b1304c20c8c89d7423199e27582b212fccdeb51d --- /dev/null +++ b/common/test/keyboards/baseline/k_000___null_keyboard.kmn @@ -0,0 +1,11 @@ +store(&NAME) '000 - null keyboard' +c Description: Tests null keyboard +c keys: [K_A][RALT K_B][SHIFT K_C] +c expected: aC +c context: + +store(&version) '6.0' + +begin Unicode > use(Main) + +group(Main) using keys diff --git a/common/test/keyboards/baseline/k_000___null_keyboard.kmx b/common/test/keyboards/baseline/k_000___null_keyboard.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2a49864d0044876a4e4de92c762e54c6791ce423 Binary files /dev/null and b/common/test/keyboards/baseline/k_000___null_keyboard.kmx differ diff --git a/core/tests/unit/kmx/001 - basic input UnicodeI.kmn b/common/test/keyboards/baseline/k_001___basic_input_unicodei.kmn similarity index 88% rename from core/tests/unit/kmx/001 - basic input UnicodeI.kmn rename to common/test/keyboards/baseline/k_001___basic_input_unicodei.kmn index 79eb4dee700a7fca7a6f6bdaca228e388c240ee6..446c0e8f1d98e724009ec61447aac2614aceabff 100644 --- a/core/tests/unit/kmx/001 - basic input UnicodeI.kmn +++ b/common/test/keyboards/baseline/k_001___basic_input_unicodei.kmn @@ -1,3 +1,4 @@ +store(&NAME) '001 - basic input UnicodeI' c Description: Tests basic input with simple context rules, ANSI characters used only c keys: [SHIFT K_A][SHIFT K_B][SHIFT K_C][SHIFT K_SPACE][SHIFT K_D][SHIFT K_E][SHIFT K_F] c expected: abc def diff --git a/common/test/keyboards/baseline/k_001___basic_input_unicodei.kmx b/common/test/keyboards/baseline/k_001___basic_input_unicodei.kmx new file mode 100644 index 0000000000000000000000000000000000000000..82f60cd001d0ba9bf984253ea81e87a41d1a3df4 Binary files /dev/null and b/common/test/keyboards/baseline/k_001___basic_input_unicodei.kmx differ diff --git a/core/tests/unit/kmx/002 - basic input Unicode.kmn b/common/test/keyboards/baseline/k_002___basic_input_unicode.kmn similarity index 87% rename from core/tests/unit/kmx/002 - basic input Unicode.kmn rename to common/test/keyboards/baseline/k_002___basic_input_unicode.kmn index bcbcd718d8af640f5bd7c2971f09b31d09153e50..04c6df9f4a647292d322cbb60540cf5684c71aa5 100644 --- a/core/tests/unit/kmx/002 - basic input Unicode.kmn +++ b/common/test/keyboards/baseline/k_002___basic_input_unicode.kmn @@ -1,7 +1,8 @@ +store(&NAME) '002 - basic input Unicode' c Description: Tests basic input with simple context rules (Unicode) c keys: [SHIFT K_A][SHIFT K_B][SHIFT K_C][SHIFT K_SPACE][SHIFT K_D][SHIFT K_E][SHIFT K_F] c expected: \u0E01\u0E02\u0E03\u0020\u0E04\u0E05\u0E06 -c context: +c context: store(&version) '6.0' diff --git a/common/test/keyboards/baseline/k_002___basic_input_unicode.kmx b/common/test/keyboards/baseline/k_002___basic_input_unicode.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5f1497a29e0dd26ad493c5cf04d65c69f09cd7e9 Binary files /dev/null and b/common/test/keyboards/baseline/k_002___basic_input_unicode.kmx differ diff --git a/core/tests/unit/kmx/003 - nul.kmn b/common/test/keyboards/baseline/k_003___nul.kmn similarity index 89% rename from core/tests/unit/kmx/003 - nul.kmn rename to common/test/keyboards/baseline/k_003___nul.kmn index 935d34402fbe3331845ff302795c063f031c3be0..32f6e84839ab4dbd4734aec729850010bc15505e 100644 --- a/core/tests/unit/kmx/003 - nul.kmn +++ b/common/test/keyboards/baseline/k_003___nul.kmn @@ -1,3 +1,4 @@ +store(&NAME) '003 - nul' c Description: Tests nul context c keys: [K_A][K_A][K_A] c expected: cd diff --git a/common/test/keyboards/baseline/k_003___nul.kmx b/common/test/keyboards/baseline/k_003___nul.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9a5e835e04af55f0c3f11b84877e9e2d3df8e107 Binary files /dev/null and b/common/test/keyboards/baseline/k_003___nul.kmx differ diff --git a/core/tests/unit/kmx/004 - basic input (shift 2).kmn b/common/test/keyboards/baseline/k_004___basic_input__shift_2_.kmn similarity index 90% rename from core/tests/unit/kmx/004 - basic input (shift 2).kmn rename to common/test/keyboards/baseline/k_004___basic_input__shift_2_.kmn index be91d698c5fcef3f455b2699ee14b6c431e4d290..d87821442735f25e869300d66ba34e5b10a88929 100644 --- a/core/tests/unit/kmx/004 - basic input (shift 2).kmn +++ b/common/test/keyboards/baseline/k_004___basic_input__shift_2_.kmn @@ -1,3 +1,4 @@ +store(&NAME) '004 - basic input (shift 2)' c Description: Tests basic vkey input with shift only (Unicode) c keys: [SHIFT K_A][SHIFT K_B][SHIFT K_C][SHIFT K_SPACE][SHIFT K_D][SHIFT K_E][SHIFT K_F] c expected: \u0E01\u0E02\u0E03\u0020\u0E04\u0E05\u0E06 diff --git a/common/test/keyboards/baseline/k_004___basic_input__shift_2_.kmx b/common/test/keyboards/baseline/k_004___basic_input__shift_2_.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c465d596d5fc7f7f50881ad8b4377414a05458cf Binary files /dev/null and b/common/test/keyboards/baseline/k_004___basic_input__shift_2_.kmx differ diff --git a/core/tests/unit/kmx/005 - nul with initial context.kmn b/common/test/keyboards/baseline/k_005___nul_with_initial_context.kmn similarity index 83% rename from core/tests/unit/kmx/005 - nul with initial context.kmn rename to common/test/keyboards/baseline/k_005___nul_with_initial_context.kmn index d838c28c6dce18abab9c7d2aba2748944972ef3f..f59016cbe184d0dba78893794b8ca3ce663cfcf6 100644 --- a/core/tests/unit/kmx/005 - nul with initial context.kmn +++ b/common/test/keyboards/baseline/k_005___nul_with_initial_context.kmn @@ -1,3 +1,4 @@ +store(&NAME) '005 - nul with initial context' c Description: Tests nul context with an initial context supplied c keys: [K_A][K_A] c expected: xdd diff --git a/common/test/keyboards/baseline/k_005___nul_with_initial_context.kmx b/common/test/keyboards/baseline/k_005___nul_with_initial_context.kmx new file mode 100644 index 0000000000000000000000000000000000000000..53f9889b32f3e3fa150a9bbfb94fe118d5f532c2 Binary files /dev/null and b/common/test/keyboards/baseline/k_005___nul_with_initial_context.kmx differ diff --git a/core/tests/unit/kmx/006 - vkey input (shift ctrl).kmn b/common/test/keyboards/baseline/k_006___vkey_input__shift_ctrl_.kmn similarity index 90% rename from core/tests/unit/kmx/006 - vkey input (shift ctrl).kmn rename to common/test/keyboards/baseline/k_006___vkey_input__shift_ctrl_.kmn index 452e071ecb1211c6523ff4203dbd3bb3b0f7e1f4..9a966aa651db7c226640e720bb77b8b2693c7879 100644 --- a/core/tests/unit/kmx/006 - vkey input (shift ctrl).kmn +++ b/common/test/keyboards/baseline/k_006___vkey_input__shift_ctrl_.kmn @@ -1,3 +1,4 @@ +store(&NAME) '006 - vkey input (shift ctrl)' c Description: Tests basic vkey input with shift and control (Unicode) c keys: [LCTRL SHIFT K_A][SHIFT K_B][RCTRL SHIFT K_C][K_SPACE][SHIFT K_D][SHIFT K_E][SHIFT K_F] c expected: \u0E01\u0E02\u0E03\u0020\u0E04\u0E05\u0E06 diff --git a/common/test/keyboards/baseline/k_006___vkey_input__shift_ctrl_.kmx b/common/test/keyboards/baseline/k_006___vkey_input__shift_ctrl_.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6651a91b1962a3a7737a59686c1eea304ba0abf1 Binary files /dev/null and b/common/test/keyboards/baseline/k_006___vkey_input__shift_ctrl_.kmx differ diff --git a/core/tests/unit/kmx/007 - vkey input (ctrl alt).kmn b/common/test/keyboards/baseline/k_007___vkey_input__ctrl_alt_.kmn similarity index 90% rename from core/tests/unit/kmx/007 - vkey input (ctrl alt).kmn rename to common/test/keyboards/baseline/k_007___vkey_input__ctrl_alt_.kmn index bae07ea09152d61e00dbecc0273315ed53981947..3c2eb42bfe0092852ee150b12a9f86c34b859c14 100644 --- a/core/tests/unit/kmx/007 - vkey input (ctrl alt).kmn +++ b/common/test/keyboards/baseline/k_007___vkey_input__ctrl_alt_.kmn @@ -1,3 +1,4 @@ +store(&NAME) '007 - vkey input (ctrl alt)' c Description: Tests basic vkey input with control and alt (Unicode) c keys: [LCTRL LALT K_A][K_B][RCTRL RALT K_C][K_SPACE][K_D][K_E][LCTRL LALT K_F] c expected: \u0E01\u0E02\u0E03\u0020\u0E04\u0E05\u0E06 diff --git a/common/test/keyboards/baseline/k_007___vkey_input__ctrl_alt_.kmx b/common/test/keyboards/baseline/k_007___vkey_input__ctrl_alt_.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3000af8a8025e65bbe785fd9b97119b138509c13 Binary files /dev/null and b/common/test/keyboards/baseline/k_007___vkey_input__ctrl_alt_.kmx differ diff --git a/core/tests/unit/kmx/008 - vkey input (ctrl alt 2).kmn b/common/test/keyboards/baseline/k_008___vkey_input__ctrl_alt_2_.kmn similarity index 86% rename from core/tests/unit/kmx/008 - vkey input (ctrl alt 2).kmn rename to common/test/keyboards/baseline/k_008___vkey_input__ctrl_alt_2_.kmn index 43b81eab010053fbc3d60981ee2047a1d7d82cb0..ac267fa15b59080de405dbf80bd137645473ace5 100644 --- a/core/tests/unit/kmx/008 - vkey input (ctrl alt 2).kmn +++ b/common/test/keyboards/baseline/k_008___vkey_input__ctrl_alt_2_.kmn @@ -1,3 +1,4 @@ +store(&NAME) '008 - vkey input (ctrl alt 2)' c Description: Tests basic vkey input with control and alt (Unicode) c keys: [LCTRL LALT K_A][LCTRL LALT K_B][LCTRL LALT K_C] c expected: \u0E01\u0E03 diff --git a/common/test/keyboards/baseline/k_008___vkey_input__ctrl_alt_2_.kmx b/common/test/keyboards/baseline/k_008___vkey_input__ctrl_alt_2_.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0f7e29779eda3a9ac306e7fb2e3a750482163bbe Binary files /dev/null and b/common/test/keyboards/baseline/k_008___vkey_input__ctrl_alt_2_.kmx differ diff --git a/core/tests/unit/kmx/012 - ralt.kmn b/common/test/keyboards/baseline/k_012___ralt.kmn similarity index 87% rename from core/tests/unit/kmx/012 - ralt.kmn rename to common/test/keyboards/baseline/k_012___ralt.kmn index a4ed290ec84fd0d104d3c4f3bb7a6ffaa5722648..8e041ad99e004d959ad0a02607476b635eb0c200 100644 --- a/core/tests/unit/kmx/012 - ralt.kmn +++ b/common/test/keyboards/baseline/k_012___ralt.kmn @@ -1,3 +1,4 @@ +store(&NAME) '012 - ralt' c Description: Tests Right Alt processing: requires Ctrl+Alt simulation off. c env.simulate_altgr: 0 c keys: [RALT K_A][RALT K_O][LCTRL LALT K_A][LCTRL LALT K_O] @@ -13,4 +14,4 @@ group(main) using keys + [RAlt K_A] > U+05D6 + [RAlt K_O] > U+05E8 + [Ctrl Alt K_A] > "b" -+ [Ctrl Alt K_O] > "c" ++ [Ctrl Alt K_O] > "c" diff --git a/common/test/keyboards/baseline/k_012___ralt.kmx b/common/test/keyboards/baseline/k_012___ralt.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3ac57c165b517b5a530db05d20d0d257e07f8d9a Binary files /dev/null and b/common/test/keyboards/baseline/k_012___ralt.kmx differ diff --git a/core/tests/unit/kmx/013 - deadkeys.kmn b/common/test/keyboards/baseline/k_013___deadkeys.kmn similarity index 88% rename from core/tests/unit/kmx/013 - deadkeys.kmn rename to common/test/keyboards/baseline/k_013___deadkeys.kmn index e462491840375dd98be7c0d0f920f3a1af26a802..d0f4876455eeb00968bc562f575dccefb238444b 100644 --- a/core/tests/unit/kmx/013 - deadkeys.kmn +++ b/common/test/keyboards/baseline/k_013___deadkeys.kmn @@ -1,3 +1,4 @@ +store(&NAME) '013 - deadkeys' c Description: Tests a simple deadkey rule in Unicode c keys: [SHIFT K_6][K_A] c expected: \u00E2 diff --git a/common/test/keyboards/baseline/k_013___deadkeys.kmx b/common/test/keyboards/baseline/k_013___deadkeys.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7f93d7d9ae9f2ed3743e3ca997647b328c37481f Binary files /dev/null and b/common/test/keyboards/baseline/k_013___deadkeys.kmx differ diff --git a/core/tests/unit/kmx/014 - groups and virtual keys.kmn b/common/test/keyboards/baseline/k_014___groups_and_virtual_keys.kmn similarity index 93% rename from core/tests/unit/kmx/014 - groups and virtual keys.kmn rename to common/test/keyboards/baseline/k_014___groups_and_virtual_keys.kmn index 20db871043ecb90c85481bef9da7b97d163104cf..81e26763b6defd39f60cec01b39d1db9c0042d34 100644 --- a/core/tests/unit/kmx/014 - groups and virtual keys.kmn +++ b/common/test/keyboards/baseline/k_014___groups_and_virtual_keys.kmn @@ -1,3 +1,4 @@ +store(&NAME) '014 - groups and virtual keys' c Description: Tests multiple groups and virtual keys with mnemonic layout c keys: [K_A][SHIFT K_2][K_A][LCTRL K_2][K_A] c expected: \u03B1\u1FB0\u1FB1 diff --git a/common/test/keyboards/baseline/k_014___groups_and_virtual_keys.kmx b/common/test/keyboards/baseline/k_014___groups_and_virtual_keys.kmx new file mode 100644 index 0000000000000000000000000000000000000000..03bb1508a55ebf46c59d21379908465c37eba734 Binary files /dev/null and b/common/test/keyboards/baseline/k_014___groups_and_virtual_keys.kmx differ diff --git a/core/tests/unit/kmx/015 - ralt 2.kmn b/common/test/keyboards/baseline/k_015___ralt_2.kmn similarity index 88% rename from core/tests/unit/kmx/015 - ralt 2.kmn rename to common/test/keyboards/baseline/k_015___ralt_2.kmn index ee87dd6f6b9758ce6c4188b37840025c8de99093..631bea8d8d8e19b6cdad7289f84da320405bbd51 100644 --- a/core/tests/unit/kmx/015 - ralt 2.kmn +++ b/common/test/keyboards/baseline/k_015___ralt_2.kmn @@ -1,3 +1,4 @@ +store(&NAME) '015 - ralt 2' c Description: Tests Right Alt processing with non-US kbds. c keys: [K_A][K_B][K_C][RALT K_A] c expected: abcd @@ -9,4 +10,3 @@ begin Unicode > use(main) group(main) using keys 'c' + [RAlt K_A] > "cd" - diff --git a/common/test/keyboards/baseline/k_015___ralt_2.kmx b/common/test/keyboards/baseline/k_015___ralt_2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0a5e1bbf434b09618983f22e84b6f9fdc7c89d0f Binary files /dev/null and b/common/test/keyboards/baseline/k_015___ralt_2.kmx differ diff --git a/core/tests/unit/kmx/017 - space mnemonic kbd.kmn b/common/test/keyboards/baseline/k_017___space_mnemonic_kbd.kmn similarity index 91% rename from core/tests/unit/kmx/017 - space mnemonic kbd.kmn rename to common/test/keyboards/baseline/k_017___space_mnemonic_kbd.kmn index 33b21536ed2aa1f4d69ed28491d2aa2acecf111b..a66fac420a9c6c27ca5c64ec2538343e97e75597 100644 --- a/core/tests/unit/kmx/017 - space mnemonic kbd.kmn +++ b/common/test/keyboards/baseline/k_017___space_mnemonic_kbd.kmn @@ -1,3 +1,4 @@ +store(&NAME) '017 - space mnemonic kbd' c Description: Tests Space handling in mnemonic keyboards (failed with Win 98) c keys: [K_A][K_B][K_SPACE][K_C][K_SPACE][K_D][K_SPACE][K_D][K_E] c expected: XYZ diff --git a/common/test/keyboards/baseline/k_017___space_mnemonic_kbd.kmx b/common/test/keyboards/baseline/k_017___space_mnemonic_kbd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0983bd248870a3724caea783d60d58875fc76173 Binary files /dev/null and b/common/test/keyboards/baseline/k_017___space_mnemonic_kbd.kmx differ diff --git a/core/tests/unit/kmx/018 - nul testing.kmn b/common/test/keyboards/baseline/k_018___nul_testing.kmn similarity index 88% rename from core/tests/unit/kmx/018 - nul testing.kmn rename to common/test/keyboards/baseline/k_018___nul_testing.kmn index 3c0cb24f2ae94816701f2bd4c293125418e76472..bc6e41206d521ec792c453ed797a8b8893ee75ce 100644 --- a/core/tests/unit/kmx/018 - nul testing.kmn +++ b/common/test/keyboards/baseline/k_018___nul_testing.kmn @@ -1,3 +1,4 @@ +store(&NAME) '018 - nul testing' c Description: Tests the processing of nul in LHS of rules c keys: [K_A][K_A] c expected: OKa @@ -12,4 +13,3 @@ group(Main) using keys nul + 'a' > 'OK' c EOF - diff --git a/common/test/keyboards/baseline/k_018___nul_testing.kmx b/common/test/keyboards/baseline/k_018___nul_testing.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bf15f3bc139270f242b4fbae8bbbd9b450bd32e6 Binary files /dev/null and b/common/test/keyboards/baseline/k_018___nul_testing.kmx differ diff --git a/core/tests/unit/kmx/019 - multiple deadkeys.kmn b/common/test/keyboards/baseline/k_019___multiple_deadkeys.kmn similarity index 94% rename from core/tests/unit/kmx/019 - multiple deadkeys.kmn rename to common/test/keyboards/baseline/k_019___multiple_deadkeys.kmn index c6b19700a035acaa03c2471dd5a83b6bc95bab5f..e70b30f08c5236a146d85e2bed3f92e52f949754 100644 --- a/core/tests/unit/kmx/019 - multiple deadkeys.kmn +++ b/common/test/keyboards/baseline/k_019___multiple_deadkeys.kmn @@ -1,3 +1,4 @@ +store(&NAME) '019 - multiple deadkeys' c Description: Tests deadkey scenarios c 1. One deadkey in context dk(1) + '1' c 2. One char and one deadkey in context 'a' dk(2) + '2' @@ -55,4 +56,4 @@ c [K_9] [K_X] [K_X] -> test that + '9' > '{' dk(9a) dk(9b) '}' dk(9c) dk(9d) dk(9b) '}' dk(9c) dk(9d) + 'x' > dk(9e) '}' dk(9f) dk(9g) -'{' dk(9a) dk(9e) '}' dk(9f) dk(9g) + 'x' > '9=OK' \ No newline at end of file +'{' dk(9a) dk(9e) '}' dk(9f) dk(9g) + 'x' > '9=OK' diff --git a/common/test/keyboards/baseline/k_019___multiple_deadkeys.kmx b/common/test/keyboards/baseline/k_019___multiple_deadkeys.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fe22a2819a535a56b6c8a43dd1239726e9575383 Binary files /dev/null and b/common/test/keyboards/baseline/k_019___multiple_deadkeys.kmx differ diff --git a/core/tests/unit/kmx/020 - deadkeys and backspace.kmn b/common/test/keyboards/baseline/k_020___deadkeys_and_backspace.kmn similarity index 95% rename from core/tests/unit/kmx/020 - deadkeys and backspace.kmn rename to common/test/keyboards/baseline/k_020___deadkeys_and_backspace.kmn index 0a3f97f4616694cbbefcb34eb2ecc7aad2f91218..cf83220f9c322ef546afc1a17e47694777903b8b 100644 --- a/core/tests/unit/kmx/020 - deadkeys and backspace.kmn +++ b/common/test/keyboards/baseline/k_020___deadkeys_and_backspace.kmn @@ -1,3 +1,4 @@ +store(&NAME) '020 - deadkeys and backspace' c Description: Tests deadkey backspacing c 1. One deadkey in context dk(1) + BKSP = nul c 2. One char and one deadkey in context 'a' dk(2) + BKSP = nul diff --git a/common/test/keyboards/baseline/k_020___deadkeys_and_backspace.kmx b/common/test/keyboards/baseline/k_020___deadkeys_and_backspace.kmx new file mode 100644 index 0000000000000000000000000000000000000000..149c2a4f97bb2bd48506ea090f64ee8594015a9e Binary files /dev/null and b/common/test/keyboards/baseline/k_020___deadkeys_and_backspace.kmx differ diff --git a/core/tests/unit/kmx/021 - options.kmn b/common/test/keyboards/baseline/k_021___options.kmn similarity index 91% rename from core/tests/unit/kmx/021 - options.kmn rename to common/test/keyboards/baseline/k_021___options.kmn index a6dbb7c1dd0e5d9a6bf1c9edc8feaf098ed3629f..3851896b84e49ca02cbc77c9e6b6c1f3e395bdb4 100644 --- a/core/tests/unit/kmx/021 - options.kmn +++ b/common/test/keyboards/baseline/k_021___options.kmn @@ -1,3 +1,4 @@ +store(&NAME) '021 - options' c Description: Tests basic option rules c keys: [K_A][K_1][K_A][K_0][K_A] c expected: no foo.foo.no foo. diff --git a/common/test/keyboards/baseline/k_021___options.kmx b/common/test/keyboards/baseline/k_021___options.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f35da34878adc50c677ebe1bc952d99bc916fc91 Binary files /dev/null and b/common/test/keyboards/baseline/k_021___options.kmx differ diff --git a/core/tests/unit/kmx/022 - options with preset.kmn b/common/test/keyboards/baseline/k_022___options_with_preset.kmn similarity index 91% rename from core/tests/unit/kmx/022 - options with preset.kmn rename to common/test/keyboards/baseline/k_022___options_with_preset.kmn index 878acc6fc0eda27f7d3d28933caff53c6c9c95ab..dbaad6e63c811f97763d6b4751174b65642430f8 100644 --- a/core/tests/unit/kmx/022 - options with preset.kmn +++ b/common/test/keyboards/baseline/k_022___options_with_preset.kmn @@ -1,3 +1,4 @@ +store(&NAME) '022 - options with preset' c Description: Tests basic option rules with a preset supplied c keys: [K_A][K_1][K_A][K_0][K_A] c expected: foo.foo.no foo. diff --git a/common/test/keyboards/baseline/k_022___options_with_preset.kmx b/common/test/keyboards/baseline/k_022___options_with_preset.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e681df83394f04ad7be451a4d82051d74924c8d4 Binary files /dev/null and b/common/test/keyboards/baseline/k_022___options_with_preset.kmx differ diff --git a/core/tests/unit/kmx/023 - options with save.kmn b/common/test/keyboards/baseline/k_023___options_with_save.kmn similarity index 86% rename from core/tests/unit/kmx/023 - options with save.kmn rename to common/test/keyboards/baseline/k_023___options_with_save.kmn index aa6c1389712075a259e0d389407485b5e87ebfe4..913bea076f345daf3cea3f9822953ed2978cf9e3 100644 --- a/core/tests/unit/kmx/023 - options with save.kmn +++ b/common/test/keyboards/baseline/k_023___options_with_save.kmn @@ -1,3 +1,4 @@ +store(&NAME) '023 - options with save' c Description: Tests basic option rules with save c keys: [K_A][K_1][K_A][K_0][K_A][K_2] c expected: no foo.foo.no foo. @@ -17,4 +18,4 @@ if(foo = '1') + 'a' > 'foo.' if(foo = '0') + 'a' > 'no foo.' + '1' > set(foo = '1') + '0' > set(foo = '0') -+ '2' > save(foo) \ No newline at end of file ++ '2' > save(foo) diff --git a/common/test/keyboards/baseline/k_023___options_with_save.kmx b/common/test/keyboards/baseline/k_023___options_with_save.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3668b7a066ef37d8ecd0334c9e3fdbd2eca1f944 Binary files /dev/null and b/common/test/keyboards/baseline/k_023___options_with_save.kmx differ diff --git a/core/tests/unit/kmx/024 - options with save and preset.kmn b/common/test/keyboards/baseline/k_024___options_with_save_and_preset.kmn similarity index 82% rename from core/tests/unit/kmx/024 - options with save and preset.kmn rename to common/test/keyboards/baseline/k_024___options_with_save_and_preset.kmn index e8ecd57944961be192d17607f72912cfcb53df86..0c3004c3e32a52d477b38fdced5812fa8f2abc86 100644 --- a/core/tests/unit/kmx/024 - options with save and preset.kmn +++ b/common/test/keyboards/baseline/k_024___options_with_save_and_preset.kmn @@ -1,3 +1,4 @@ +store(&NAME) '024 - options with save and preset' c Description: Tests basic option rules with save c keys: [K_A][K_1][K_A][K_0][K_A][K_2] c expected: foo.foo.no foo. @@ -18,4 +19,4 @@ if(foo = '1') + 'a' > 'foo.' if(foo = '0') + 'a' > 'no foo.' + '1' > set(foo = '1') + '0' > set(foo = '0') -if(foo = '0') + '2' > save(foo) +if(foo = '0') + '2' > save(foo) diff --git a/common/test/keyboards/baseline/k_024___options_with_save_and_preset.kmx b/common/test/keyboards/baseline/k_024___options_with_save_and_preset.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1fecdfac2131f0ebb90d36134ae99c5f0d5e1342 Binary files /dev/null and b/common/test/keyboards/baseline/k_024___options_with_save_and_preset.kmx differ diff --git a/core/tests/unit/kmx/025 - options with reset.kmn b/common/test/keyboards/baseline/k_025___options_with_reset.kmn similarity index 90% rename from core/tests/unit/kmx/025 - options with reset.kmn rename to common/test/keyboards/baseline/k_025___options_with_reset.kmn index 2fea1b0ac4b66f506e6f552e03cbabb6eb13323a..13a0d69283759787c8593009b6c419c6e354c5d8 100644 --- a/core/tests/unit/kmx/025 - options with reset.kmn +++ b/common/test/keyboards/baseline/k_025___options_with_reset.kmn @@ -1,3 +1,4 @@ +store(&NAME) '025 - options with reset' c Description: Tests basic option rules with reset c keys: [K_A][K_1][K_A][K_0][K_A][K_3] c expected: foo.foo.no foo. diff --git a/common/test/keyboards/baseline/k_025___options_with_reset.kmx b/common/test/keyboards/baseline/k_025___options_with_reset.kmx new file mode 100644 index 0000000000000000000000000000000000000000..028f81cb5feb143b688f8ea96ef43bcce6d86368 Binary files /dev/null and b/common/test/keyboards/baseline/k_025___options_with_reset.kmx differ diff --git a/core/tests/unit/kmx/026 - system stores.kmn b/common/test/keyboards/baseline/k_026___system_stores.kmn similarity index 95% rename from core/tests/unit/kmx/026 - system stores.kmn rename to common/test/keyboards/baseline/k_026___system_stores.kmn index a9f537e9320b3e67b4917a5e882a948b9cb03ce8..0538c51364bfb902d83590bbca6a070553c00f9e 100644 --- a/core/tests/unit/kmx/026 - system stores.kmn +++ b/common/test/keyboards/baseline/k_026___system_stores.kmn @@ -1,3 +1,4 @@ +store(&NAME) '026 - system stores' c Description: Tests platform and baselayout system store rules c keys: [K_1][K_2][K_3][K_4][K_A][K_B] c expected: windows.desktop.hardware.native.en-US.kbdus.dll. diff --git a/common/test/keyboards/baseline/k_026___system_stores.kmx b/common/test/keyboards/baseline/k_026___system_stores.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bb918cf1429b4e57b68ea4d8bd08e226d558426d Binary files /dev/null and b/common/test/keyboards/baseline/k_026___system_stores.kmx differ diff --git a/core/tests/unit/kmx/027 - system stores 2.kmn b/common/test/keyboards/baseline/k_027___system_stores_2.kmn similarity index 95% rename from core/tests/unit/kmx/027 - system stores 2.kmn rename to common/test/keyboards/baseline/k_027___system_stores_2.kmn index 8d96e999c4132921330f974da997732d4c84e9c9..95457c84639c049ee89335138799e6964b32c02a 100644 --- a/core/tests/unit/kmx/027 - system stores 2.kmn +++ b/common/test/keyboards/baseline/k_027___system_stores_2.kmn @@ -1,3 +1,4 @@ +store(&NAME) '027 - system stores 2' c Description: Tests platform and baselayout system store rules c keys: [K_1][K_2][K_3][K_4][K_A][K_B] c expected: linux.desktop.hardware.native.fr-FR.kbdfr.dll. diff --git a/common/test/keyboards/baseline/k_027___system_stores_2.kmx b/common/test/keyboards/baseline/k_027___system_stores_2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dac90ab985bd96e1b54a14967406fb4236e80d09 Binary files /dev/null and b/common/test/keyboards/baseline/k_027___system_stores_2.kmx differ diff --git a/core/tests/unit/kmx/028 - smp.kmn b/common/test/keyboards/baseline/k_028___smp.kmn similarity index 94% rename from core/tests/unit/kmx/028 - smp.kmn rename to common/test/keyboards/baseline/k_028___smp.kmn index 5bfbbe4bd267a5c556226fa7380bd484f7fdbbcb..7c1eaaba960bc3ec59220b5784ebfafe633bb084 100644 --- a/core/tests/unit/kmx/028 - smp.kmn +++ b/common/test/keyboards/baseline/k_028___smp.kmn @@ -1,3 +1,4 @@ +store(&NAME) '028 - smp' c Description: Tests SMP characters; see #4361 [1-4], #5561 [5] c keys: [K_1][K_2][K_3][K_4][K_5] c expected: \U0001F601yx diff --git a/common/test/keyboards/baseline/k_028___smp.kmx b/common/test/keyboards/baseline/k_028___smp.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f343f969e9bde1431c12375cf7a6c7c68dad0b26 Binary files /dev/null and b/common/test/keyboards/baseline/k_028___smp.kmx differ diff --git a/core/tests/unit/kmx/029 - beep.kmn b/common/test/keyboards/baseline/k_029___beep.kmn similarity index 85% rename from core/tests/unit/kmx/029 - beep.kmn rename to common/test/keyboards/baseline/k_029___beep.kmn index 76e51e620608bc1b4a336586c5518d30f27e5ded..65e650ee44bd82b2b9cf82172ed49943af0149fb 100644 --- a/core/tests/unit/kmx/029 - beep.kmn +++ b/common/test/keyboards/baseline/k_029___beep.kmn @@ -1,3 +1,4 @@ +store(&NAME) '029 - beep' c Description: Tests beep c keys: [K_1] c expected: \b diff --git a/common/test/keyboards/baseline/k_029___beep.kmx b/common/test/keyboards/baseline/k_029___beep.kmx new file mode 100644 index 0000000000000000000000000000000000000000..abf8b899836172c2802a5c5f3972aa85ee03ab52 Binary files /dev/null and b/common/test/keyboards/baseline/k_029___beep.kmx differ diff --git a/core/tests/unit/kmx/030 - multiple groups.kmn b/common/test/keyboards/baseline/k_030___multiple_groups.kmn similarity index 87% rename from core/tests/unit/kmx/030 - multiple groups.kmn rename to common/test/keyboards/baseline/k_030___multiple_groups.kmn index e29b7bd293efdd34bebb1bc805f6f67900760af9..b9148827bc8ebc3c01d3a7a58d7372886814a38c 100644 --- a/core/tests/unit/kmx/030 - multiple groups.kmn +++ b/common/test/keyboards/baseline/k_030___multiple_groups.kmn @@ -1,7 +1,8 @@ +store(&NAME) "030 - multiple groups" c Description: Tests multiple groups. Purpose here is to interleave output and backspaces from kmx processor to consumer c keys: [K_1][K_2] c expected: abc -c context: +c context: store(&version) '10.0' diff --git a/common/test/keyboards/baseline/k_030___multiple_groups.kmx b/common/test/keyboards/baseline/k_030___multiple_groups.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e27ee4dd08c08fc1f45267c54dbfb6dd1bfe5109 Binary files /dev/null and b/common/test/keyboards/baseline/k_030___multiple_groups.kmx differ diff --git a/core/tests/unit/kmx/031 - caps lock.kmn b/common/test/keyboards/baseline/k_031___caps_lock.kmn similarity index 93% rename from core/tests/unit/kmx/031 - caps lock.kmn rename to common/test/keyboards/baseline/k_031___caps_lock.kmn index 8a3f3468b1127e75be99a73c7e9efea22f6d089c..d14b8ad56ba95366082a4b60e51d90b080845e0b 100644 --- a/core/tests/unit/kmx/031 - caps lock.kmn +++ b/common/test/keyboards/baseline/k_031___caps_lock.kmn @@ -1,3 +1,4 @@ +store(&NAME) '031 - caps lock' c Description: Tests Caps Lock c keys: [K_1][SHIFT K_2][SHIFT K_3][K_A][SHIFT K_B] c expected: pass.pass.pass.pass.pass. diff --git a/common/test/keyboards/baseline/k_031___caps_lock.kmx b/common/test/keyboards/baseline/k_031___caps_lock.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5fe3e4fbd74b8e928a0acf7e052369c0de919bae Binary files /dev/null and b/common/test/keyboards/baseline/k_031___caps_lock.kmx differ diff --git a/core/tests/unit/kmx/032 - caps control.kmn b/common/test/keyboards/baseline/k_032___caps_control.kmn similarity index 96% rename from core/tests/unit/kmx/032 - caps control.kmn rename to common/test/keyboards/baseline/k_032___caps_control.kmn index 203026da36181afca8155d38381d9ddd91e4968a..884fb41a6d5b53f86295a628e7131d265745955e 100644 --- a/core/tests/unit/kmx/032 - caps control.kmn +++ b/common/test/keyboards/baseline/k_032___caps_control.kmn @@ -1,3 +1,4 @@ +store(&NAME) '032 - caps control' c Description: Tests Caps Lock env set c keys: [K_1][K_CAPS][K_2][SHIFT K_3][K_4][K_CAPS][K_5][K_CAPS][K_6][K_SHIFT][K_7] c expected: pass.pass.pass.pass.pass.pass.pass. diff --git a/common/test/keyboards/baseline/k_032___caps_control.kmx b/common/test/keyboards/baseline/k_032___caps_control.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1914d1954bb7186f7edb96a9a28e64df0ce182d6 Binary files /dev/null and b/common/test/keyboards/baseline/k_032___caps_control.kmx differ diff --git a/core/tests/unit/kmx/033 - caps always off.kmn b/common/test/keyboards/baseline/k_033___caps_always_off.kmn similarity index 91% rename from core/tests/unit/kmx/033 - caps always off.kmn rename to common/test/keyboards/baseline/k_033___caps_always_off.kmn index 056fcd895104635eb5b6c8e8d422dbf0fc684327..912f2c5ac0d6f3ed1d2dc5d76b0a78bef2630ba4 100644 --- a/core/tests/unit/kmx/033 - caps always off.kmn +++ b/common/test/keyboards/baseline/k_033___caps_always_off.kmn @@ -1,3 +1,4 @@ +store(&NAME) '033 - caps always off' c Description: Tests Caps Lock always off c keys: [K_1][K_CAPS][K_2][K_CAPS][K_3] c expected: pass.pass.pass. diff --git a/common/test/keyboards/baseline/k_033___caps_always_off.kmx b/common/test/keyboards/baseline/k_033___caps_always_off.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cb9a71a0460da245d17985bf76235ebdf6c93080 Binary files /dev/null and b/common/test/keyboards/baseline/k_033___caps_always_off.kmx differ diff --git a/core/tests/unit/kmx/034 - options double set reset.kmn b/common/test/keyboards/baseline/k_034___options_double_set_reset.kmn similarity index 90% rename from core/tests/unit/kmx/034 - options double set reset.kmn rename to common/test/keyboards/baseline/k_034___options_double_set_reset.kmn index 2e8e754b95a3d85fa91f688f505beca70df73836..3fe9225ecadb1d3f3f3c6320f194c4731bce003d 100644 --- a/core/tests/unit/kmx/034 - options double set reset.kmn +++ b/common/test/keyboards/baseline/k_034___options_double_set_reset.kmn @@ -1,3 +1,4 @@ +store(&NAME) '034 - options double set reset' c Description: Tests basic option rules with save reset+set+reset c keys: [K_A][K_A] c expected: foo.foo. diff --git a/common/test/keyboards/baseline/k_034___options_double_set_reset.kmx b/common/test/keyboards/baseline/k_034___options_double_set_reset.kmx new file mode 100644 index 0000000000000000000000000000000000000000..df8eb8062a535df0881c3e960f8b5232fdf6bc94 Binary files /dev/null and b/common/test/keyboards/baseline/k_034___options_double_set_reset.kmx differ diff --git a/core/tests/unit/kmx/035 - options double set staged.kmn b/common/test/keyboards/baseline/k_035___options_double_set_staged.kmn similarity index 90% rename from core/tests/unit/kmx/035 - options double set staged.kmn rename to common/test/keyboards/baseline/k_035___options_double_set_staged.kmn index e92e9bacac766a44fc902911ad276bf5e3ad1de8..75d1b81b89b7c09d42b29b0a488260b45e498c10 100644 --- a/core/tests/unit/kmx/035 - options double set staged.kmn +++ b/common/test/keyboards/baseline/k_035___options_double_set_staged.kmn @@ -1,3 +1,4 @@ +store(&NAME) '035 - options double set staged' c Description: Tests basic option rules with save reset+set+reset c keys: [K_A][K_B][K_C][K_B][K_A] c expected: foo.foo. diff --git a/common/test/keyboards/baseline/k_035___options_double_set_staged.kmx b/common/test/keyboards/baseline/k_035___options_double_set_staged.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e112a0740f57c46c61d5d72a322bfb0922edaf06 Binary files /dev/null and b/common/test/keyboards/baseline/k_035___options_double_set_staged.kmx differ diff --git a/core/tests/unit/kmx/036 - options - double reset staged.kmn b/common/test/keyboards/baseline/k_036___options___double_reset_staged.kmn similarity index 88% rename from core/tests/unit/kmx/036 - options - double reset staged.kmn rename to common/test/keyboards/baseline/k_036___options___double_reset_staged.kmn index 5a9144f3f7d444bd48c727f3c06c33966995ae54..53157b487d3004ebda8d63eac18dda74b76d0c5c 100644 --- a/core/tests/unit/kmx/036 - options - double reset staged.kmn +++ b/common/test/keyboards/baseline/k_036___options___double_reset_staged.kmn @@ -1,3 +1,4 @@ +store(&NAME) '036 - options - double reset staged' c Description: Tests basic option rules with save reset+reset c keys: [K_A][K_B][K_B][K_A] c expected: foo.foo. diff --git a/common/test/keyboards/baseline/k_036___options___double_reset_staged.kmx b/common/test/keyboards/baseline/k_036___options___double_reset_staged.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ccb05e04c1faa64a540ea3bf3307c988ddfd2e50 Binary files /dev/null and b/common/test/keyboards/baseline/k_036___options___double_reset_staged.kmx differ diff --git a/core/tests/unit/kmx/037 - options - double reset.kmn b/common/test/keyboards/baseline/k_037___options___double_reset.kmn similarity index 89% rename from core/tests/unit/kmx/037 - options - double reset.kmn rename to common/test/keyboards/baseline/k_037___options___double_reset.kmn index 5d2eb1d15ed14b7789122e933fd60e9ad1bd302a..05e5fe7b024d3b118e922f812ee8f37b379c39c1 100644 --- a/core/tests/unit/kmx/037 - options - double reset.kmn +++ b/common/test/keyboards/baseline/k_037___options___double_reset.kmn @@ -1,3 +1,4 @@ +store(&NAME) '037 - options - double reset' c Description: Tests basic option rules with save reset+reset c keys: [K_A][K_A] c expected: foo.foo. diff --git a/common/test/keyboards/baseline/k_037___options___double_reset.kmx b/common/test/keyboards/baseline/k_037___options___double_reset.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eed688349c9217c488bedcd573382d937efc8fe4 Binary files /dev/null and b/common/test/keyboards/baseline/k_037___options___double_reset.kmx differ diff --git a/core/tests/unit/kmx/038 - punctkeys.kmn b/common/test/keyboards/baseline/k_038___punctkeys.kmn similarity index 95% rename from core/tests/unit/kmx/038 - punctkeys.kmn rename to common/test/keyboards/baseline/k_038___punctkeys.kmn index fc893993b4f85cb02286346a1f6ad83add81cd55..33f9c052973890a3c6d3abe0d65b8c2eb18281b3 100644 --- a/core/tests/unit/kmx/038 - punctkeys.kmn +++ b/common/test/keyboards/baseline/k_038___punctkeys.kmn @@ -1,3 +1,4 @@ +store(&NAME) '038 - punctkeys' c Description: Tests punctuation keys (Unicode) c keys: [K_A][K_COLON][K_A][K_EQUAL][K_A][K_COMMA][K_A][K_HYPHEN][K_A][K_PERIOD][K_A][K_SLASH][K_A][K_BKQUOTE][K_A][K_LBRKT][K_A][K_BKSLASH][K_A][K_RBRKT][K_A][K_QUOTE][K_A][K_oE2] c expected: efghijklmnop diff --git a/common/test/keyboards/baseline/k_038___punctkeys.kmx b/common/test/keyboards/baseline/k_038___punctkeys.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8166409f5f32d1c631f1cdaaeabb6f0a4d19a7d7 Binary files /dev/null and b/common/test/keyboards/baseline/k_038___punctkeys.kmx differ diff --git a/core/tests/unit/kmx/039 - generic ctrlalt.kmn b/common/test/keyboards/baseline/k_039___generic_ctrlalt.kmn similarity index 88% rename from core/tests/unit/kmx/039 - generic ctrlalt.kmn rename to common/test/keyboards/baseline/k_039___generic_ctrlalt.kmn index d5404138bf25a1ebc91031b638c3dc0c27adf848..1bbb1de66112c2deb47df970a9c707955fdf6210 100644 --- a/core/tests/unit/kmx/039 - generic ctrlalt.kmn +++ b/common/test/keyboards/baseline/k_039___generic_ctrlalt.kmn @@ -1,3 +1,4 @@ +store(&NAME) '039 - generic ctrlalt' c Description: Tests generic alt and control (Unicode) c keys: [K_A][K_A][LCTRL K_B][K_A][LALT K_C][K_A][RCTRL K_B][K_A][RALT K_C] c expected: abcbc diff --git a/common/test/keyboards/baseline/k_039___generic_ctrlalt.kmx b/common/test/keyboards/baseline/k_039___generic_ctrlalt.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1bf180a31c8c53250e335c5cd034092f41c99438 Binary files /dev/null and b/common/test/keyboards/baseline/k_039___generic_ctrlalt.kmx differ diff --git a/core/tests/unit/kmx/040 - long context.kmn b/common/test/keyboards/baseline/k_040___long_context.kmn similarity index 91% rename from core/tests/unit/kmx/040 - long context.kmn rename to common/test/keyboards/baseline/k_040___long_context.kmn index 994f38bede0d9ff4bdfd923d826675a16247948f..f570d2571082ef6577c6d5e34b71e80ce218102d 100644 --- a/core/tests/unit/kmx/040 - long context.kmn +++ b/common/test/keyboards/baseline/k_040___long_context.kmn @@ -1,3 +1,4 @@ +store(&NAME) '040 - long context' c Description: Tests context longer than 64 chars c keys: [K_SPACE][K_F] c expected: 012345678901234567890123456789012345678901234567890123456789012\u0020 diff --git a/common/test/keyboards/baseline/k_040___long_context.kmx b/common/test/keyboards/baseline/k_040___long_context.kmx new file mode 100644 index 0000000000000000000000000000000000000000..55a88a77abb2acf83872b6a12dc061dce250738f Binary files /dev/null and b/common/test/keyboards/baseline/k_040___long_context.kmx differ diff --git a/core/tests/unit/kmx/041 - long context and deadkeys.kmn b/common/test/keyboards/baseline/k_041___long_context_and_deadkeys.kmn similarity index 96% rename from core/tests/unit/kmx/041 - long context and deadkeys.kmn rename to common/test/keyboards/baseline/k_041___long_context_and_deadkeys.kmn index 9675485c96d7424821714fbce7d2678d7dae030d..455fa1c41cbc62d197edcee9042ffd08592077e3 100644 --- a/core/tests/unit/kmx/041 - long context and deadkeys.kmn +++ b/common/test/keyboards/baseline/k_041___long_context_and_deadkeys.kmn @@ -1,3 +1,4 @@ +store(&NAME) '041 - long context and deadkeys' c Description: Tests that we don't split a dk in context:set. Note that we start with a context c with length MAXCONTEXT-1 (abc...fgh is 60 characters/bytes long + 3 bytes for dk(1)). c keys: [K_Z][K_1][K_2][K_3][K_4] diff --git a/common/test/keyboards/baseline/k_041___long_context_and_deadkeys.kmx b/common/test/keyboards/baseline/k_041___long_context_and_deadkeys.kmx new file mode 100644 index 0000000000000000000000000000000000000000..de2b1d5020c9941e3a57d1734085ca1dd0abe11d Binary files /dev/null and b/common/test/keyboards/baseline/k_041___long_context_and_deadkeys.kmx differ diff --git a/core/tests/unit/kmx/042 - long context and split deadkeys.kmn b/common/test/keyboards/baseline/k_042___long_context_and_split_deadkeys.kmn similarity index 93% rename from core/tests/unit/kmx/042 - long context and split deadkeys.kmn rename to common/test/keyboards/baseline/k_042___long_context_and_split_deadkeys.kmn index 457dea34f675d8f34820357f2d3aa090b14ced7a..ce31d18e28228f0ae7542b5a54d9e836c448d072 100644 --- a/core/tests/unit/kmx/042 - long context and split deadkeys.kmn +++ b/common/test/keyboards/baseline/k_042___long_context_and_split_deadkeys.kmn @@ -1,3 +1,4 @@ +store(&NAME) '042 - long context and split deadkeys' c Description: Tests that we don't split a dk in context. Note that we start with a context with length MAXCONTEXT. c keys: [K_Z][K_SPACE][K_1][K_2] c context: @@ -20,4 +21,3 @@ dk(1) 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk' + ' ' > c Convert to a visible result: 'defghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk ' + '1' > 'def' dk(1) 'abcdef' + '2' > 'PASS' - diff --git a/common/test/keyboards/baseline/k_042___long_context_and_split_deadkeys.kmx b/common/test/keyboards/baseline/k_042___long_context_and_split_deadkeys.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fbe552d53b0f731852fd07a3aa5831d25cda51f8 Binary files /dev/null and b/common/test/keyboards/baseline/k_042___long_context_and_split_deadkeys.kmx differ diff --git a/core/tests/unit/kmx/043 - output and keystroke.kmn b/common/test/keyboards/baseline/k_043___output_and_keystroke.kmn similarity index 90% rename from core/tests/unit/kmx/043 - output and keystroke.kmn rename to common/test/keyboards/baseline/k_043___output_and_keystroke.kmn index 6a5d0c6085efec54b141b3780adc34119ca0c8d3..4c6409c1c7125c8c5ea2ce40851302b0b2815700 100644 --- a/core/tests/unit/kmx/043 - output and keystroke.kmn +++ b/common/test/keyboards/baseline/k_043___output_and_keystroke.kmn @@ -1,3 +1,4 @@ +store(&NAME) '043 - output and keystroke' c Description: Tests the 'emit default key' function by having an empty 'using keys' final group c keys: [K_1][K_2][K_3] c expected: abd3 diff --git a/common/test/keyboards/baseline/k_043___output_and_keystroke.kmx b/common/test/keyboards/baseline/k_043___output_and_keystroke.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a25aae26a641719fa2715c7c81d3bb9b575b42ca Binary files /dev/null and b/common/test/keyboards/baseline/k_043___output_and_keystroke.kmx differ diff --git a/core/tests/unit/kmx/044 - if and context.kmn b/common/test/keyboards/baseline/k_044___if_and_context.kmn similarity index 91% rename from core/tests/unit/kmx/044 - if and context.kmn rename to common/test/keyboards/baseline/k_044___if_and_context.kmn index 98f4bf98534b8fa00a41aa4acb14c619aee90d0c..352490325ccdfd0db93a101b8929026b3abbe9ea 100644 --- a/core/tests/unit/kmx/044 - if and context.kmn +++ b/common/test/keyboards/baseline/k_044___if_and_context.kmn @@ -1,3 +1,4 @@ +store(&NAME) '044 - if and context' c Description: Tests that context(x) takes if() statements into account. See #4275. c keys: [K_A][K_B] c expected: ex diff --git a/common/test/keyboards/baseline/k_044___if_and_context.kmx b/common/test/keyboards/baseline/k_044___if_and_context.kmx new file mode 100644 index 0000000000000000000000000000000000000000..60c0c6300a6b6337cf3f02886ffdcaffb26c0183 Binary files /dev/null and b/common/test/keyboards/baseline/k_044___if_and_context.kmx differ diff --git a/core/tests/unit/kmx/045 - deadkey and context.kmn b/common/test/keyboards/baseline/k_045___deadkey_and_context.kmn similarity index 90% rename from core/tests/unit/kmx/045 - deadkey and context.kmn rename to common/test/keyboards/baseline/k_045___deadkey_and_context.kmn index 09d276782804f0911bdeda177530d9d1c68276e6..c79953a05b8cfa7a0041a780429b0b4dde2493e5 100644 --- a/core/tests/unit/kmx/045 - deadkey and context.kmn +++ b/common/test/keyboards/baseline/k_045___deadkey_and_context.kmn @@ -1,3 +1,4 @@ +store(&NAME) '045 - deadkey and context' c Description: Tests that context emits deadkeys correctly. See #4275. c keys: [K_Y][K_Z][SHIFT K_SLASH] c expected: correct diff --git a/common/test/keyboards/baseline/k_045___deadkey_and_context.kmx b/common/test/keyboards/baseline/k_045___deadkey_and_context.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4b1e3bfb2aa31a9c5885a151a395d08e36c9a9fc Binary files /dev/null and b/common/test/keyboards/baseline/k_045___deadkey_and_context.kmx differ diff --git a/core/tests/unit/kmx/046 - deadkey and contextex.kmn b/common/test/keyboards/baseline/k_046___deadkey_and_contextex.kmn similarity index 89% rename from core/tests/unit/kmx/046 - deadkey and contextex.kmn rename to common/test/keyboards/baseline/k_046___deadkey_and_contextex.kmn index 390e01df2d43b9c5bb155d413950eb639eb46c90..48ad796c3e5002905f5dae54d4c0312bd5fa5c31 100644 --- a/core/tests/unit/kmx/046 - deadkey and contextex.kmn +++ b/common/test/keyboards/baseline/k_046___deadkey_and_contextex.kmn @@ -1,3 +1,4 @@ +store(&NAME) '046 - deadkey and contextex' c Description: Tests that context() emits deadkeys correctly. See #4275. c keys: [K_Y][SHIFT K_M][SHIFT K_SLASH] c expected: correct diff --git a/common/test/keyboards/baseline/k_046___deadkey_and_contextex.kmx b/common/test/keyboards/baseline/k_046___deadkey_and_contextex.kmx new file mode 100644 index 0000000000000000000000000000000000000000..618eefbf27fa97b51828277312f179cc1a9aecfd Binary files /dev/null and b/common/test/keyboards/baseline/k_046___deadkey_and_contextex.kmx differ diff --git a/core/tests/unit/kmx/047 - caps always off initially on.kmn b/common/test/keyboards/baseline/k_047___caps_always_off_initially_on.kmn similarity index 90% rename from core/tests/unit/kmx/047 - caps always off initially on.kmn rename to common/test/keyboards/baseline/k_047___caps_always_off_initially_on.kmn index 014a15d583edf384933ed665fd855bf9fca02dfa..4c0b69136583e1ff7a736bd2a9997a9caaae6ac9 100644 --- a/core/tests/unit/kmx/047 - caps always off initially on.kmn +++ b/common/test/keyboards/baseline/k_047___caps_always_off_initially_on.kmn @@ -1,3 +1,4 @@ +store(&NAME) '047 - caps always off initially on' c Description: Tests Caps Lock always off, entry to the test has Caps Lock c on to test that it is then switched off on first keystroke event. c keys: [K_1][K_CAPS][K_2][K_CAPS][K_3] diff --git a/common/test/keyboards/baseline/k_047___caps_always_off_initially_on.kmx b/common/test/keyboards/baseline/k_047___caps_always_off_initially_on.kmx new file mode 100644 index 0000000000000000000000000000000000000000..301fcddc0469177249bea6a3887abb6daae0cf5d Binary files /dev/null and b/common/test/keyboards/baseline/k_047___caps_always_off_initially_on.kmx differ diff --git a/core/tests/unit/kmx/048 - modifier keys keep context.kmn b/common/test/keyboards/baseline/k_048___modifier_keys_keep_context.kmn similarity index 85% rename from core/tests/unit/kmx/048 - modifier keys keep context.kmn rename to common/test/keyboards/baseline/k_048___modifier_keys_keep_context.kmn index 629b9b24221b93a1f8647f454f76195a9ab09b5d..bb0cfc4df5d2eca0b4e7734cde0337365cedc8ce 100644 --- a/core/tests/unit/kmx/048 - modifier keys keep context.kmn +++ b/common/test/keyboards/baseline/k_048___modifier_keys_keep_context.kmn @@ -1,3 +1,4 @@ +store(&NAME) '048 - modifier keys keep context' c Description: Tests that modifier keys don't reset context (#5591) c keys: [K_A][K_SHIFT][K_B][K_A][K_ALT][K_B][K_A][K_CAPS][K_B] c expected: pass.pass.pass. diff --git a/common/test/keyboards/baseline/k_048___modifier_keys_keep_context.kmx b/common/test/keyboards/baseline/k_048___modifier_keys_keep_context.kmx new file mode 100644 index 0000000000000000000000000000000000000000..98ca5a6dbe39d8e012c3f744a706235d18dbc689 Binary files /dev/null and b/common/test/keyboards/baseline/k_048___modifier_keys_keep_context.kmx differ diff --git a/common/test/keyboards/build.sh b/common/test/keyboards/build.sh index 0a8d1782a5701f962876f207b716097a9e94bb42..cbf5863e374d5e5bb0ef36864232e3562f13e91f 100755 --- a/common/test/keyboards/build.sh +++ b/common/test/keyboards/build.sh @@ -29,7 +29,9 @@ display_usage() { for d in "$THIS_DIR/"*/; do d="$(basename "$d")" - echo " $d" + if [ "$d" != "invalid" ]; then + echo " $d" + fi done echo @@ -122,7 +124,9 @@ fi if [ ${#TARGETS[@]} == 0 ]; then for d in "$THIS_DIR/"*/; do d="$(basename "$d")" - TARGETS+=("$d") + if [ "$d" != "invalid" ]; then + TARGETS+=("$d") + fi done fi diff --git a/common/test/keyboards/invalid/README.md b/common/test/keyboards/invalid/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a1a1b5e3ab91e1230ed96f7c8e745f81967ad3cf --- /dev/null +++ b/common/test/keyboards/invalid/README.md @@ -0,0 +1,163 @@ +# **Tests for kmcompxtest()** +
+ +This folder contains several kmn-files that are used for testing resulting error codes. + +Most of these tests are copied from balochi_phonetic and contain alterations of the data to produce (at least) 1 error. +
+
+ +## Naming Convention of kmn-files for using with kmcompxtest() + + CERR_404D_balochi_phonetic.kmn + + +The naming convention of the files is as follows: + +* All Files **MUST** start with CERR_ followed by 4 characters and an underscore. + +* After the second underscore all combination of char can be used. + +* The 4 characters following CERR_ correspond to the last 4 digits of the error code which is expected to be produced by this file. + + ( e.g. CERR_404D_balochi_phonetic.kmn should produce error 0x0000404D). + +
+
+ +While running, kmcompxtest extracts those 4 characters from the Filename (e.g. 404D for CERR_404D_balochi_phonetic) and compares those to the actual error found. + +* If these 4 characters correspond to the actual error given, the test will be marked as OK. (Code 0) +
+* If these 4 characters signify an error but **no error** does occur, the test will be marked as FAILED (Code 1) +
+* If these 4 characters signify an error but this **specific error** does not occur, the test will be marked as FAILED (Code 4) +
+* If these 4 characters signify an error number that is **not correct**, the test will be marked as FAILED (Code 5) +
+* If more than 1 error is produced, only the error coded in the Filename will be detected + +
+
+ +### Tests are available for the following CERR_: + + +| | Error Number | CERR_ +| :-: | :-----------:| :------------------------------------- +| | 00000800 | CERR_LEXICAL_MODEL_MIN +| | 000008FF | CERR_LEXICAL_MODEL_MAX +| | 00000800 | CERR_LEXICAL_MODEL_MIN +| | 000008FF | CERR_LEXICAL_MODEL_MAX +| | 00000000 | CERR_None +| | 00000001 | CERR_EndOfFile +| | 00008002 | CERR_BadCallParams +| | 00008004 | CERR_CannotAllocateMemory +| | 00008005 | CERR_InfileNotExist +| | 00008006 | CERR_CannotCreateOutfile +| | 00008007 | CERR_UnableToWriteFully +| | 00008008 | CERR_CannotReadInfile +| | 00008009 | CERR_SomewhereIGotItWrong +|**X**| 0000400A | CERR_InvalidToken +| | 0000400B | CERR_InvalidBegin +| | 0000400C | CERR_InvalidName +|**X**| 0000400D | CERR_InvalidVersion +|**X**| 0000400E | CERR_InvalidLanguageLine +| | 0000400F | CERR_LayoutButNoLanguage +| | 00004010 | CERR_InvalidLayoutLine +| | 00004011 | CERR_NoVersionLine +| | 00004012 | CERR_InvalidGroupLine +|**X**| 00004013 | CERR_InvalidStoreLine +| | 00004014 | CERR_InvalidCodeInKeyPartOfRule +|**X**| 00004015 | CERR_InvalidDeadkey +|**X**| 00004016 | CERR_InvalidValue +|**X**| 00004017 | CERR_ZeroLengthString +| | 00004018 | CERR_TooManyIndexToKeyRefs +|**X**| 00004019 | CERR_UnterminatedString +| | 0000401A | CERR_StringInVirtualKeySection +| | 0000401B | CERR_AnyInVirtualKeySection +| | 0000401C | CERR_InvalidAny +|**X**| 0000401D | CERR_StoreDoesNotExist +| | 0000401E | CERR_BeepInVirtualKeySection +| | 0000401F | CERR_IndexInVirtualKeySection +| | 00004020 | CERR_InvalidIndex +| | 00004021 | CERR_OutsInVirtualKeySection +| | 00004022 | CERR_InvalidOuts +| | 00004024 | CERR_ContextInVirtualKeySection +| | 00004025 | CERR_InvalidUse +|**X**| 00004026 | CERR_GroupDoesNotExist +| | 00004027 | CERR_VirtualKeyNotAllowedHere +| | 00004028 | CERR_InvalidSwitch +|**X**| 00004029 | CERR_NoTokensFound +| | 0000402A | CERR_InvalidLineContinuation +|**X**| 0000402B | CERR_LineTooLong +| | 0000402C | CERR_InvalidCopyright +|**X**| 0000402D | CERR_CodeInvalidInThisSection +| | 0000402E | CERR_InvalidMessage +| | 0000402F | CERR_InvalidLanguageName +| | 00004030 | CERR_InvalidBitmapLine +|**X**| 00004031 | CERR_CannotReadBitmapFile +| | 00004032 | CERR_IndexDoesNotPointToAny +| | 00004033 | CERR_ReservedCharacter +|**X**| 00004034 | CERR_InvalidCharacter +| | 00004035 | CERR_InvalidCall +| | 00004036 | CERR_CallInVirtualKeySection +| | 00004037 | CERR_CodeInvalidInKeyStore +|**X**| 00004038 | CERR_CannotLoadIncludeFile +|**X**| 00004039 | CERR_60FeatureOnly_EthnologueCode +|**X**| 0000403A | CERR_60FeatureOnly_MnemonicLayout +| | 0000403B | CERR_60FeatureOnly_OldCharPosMatching +| | 0000403C | CERR_60FeatureOnly_NamedCodes +| | 0000403D | CERR_60FeatureOnly_Contextn +|**X**| 0000403E | CERR_501FeatureOnly_Call +| | 0000403F | CERR_InvalidNamedCode +|**X**| 00004040 | CERR_InvalidSystemStore +|**X**| 00004044 | CERR_60FeatureOnly_VirtualCharKey +|**X**| 00004045 | CERR_VersionAlreadyIncluded +|**X**| 00004046 | CERR_70FeatureOnly +|**X**| 00004047 | CERR_80FeatureOnly +| | 00004048 | CERR_InvalidInVirtualKeySection +|**X**| 00004049 | CERR_InvalidIf +|**X**| 0000404A | CERR_InvalidReset +|**X**| 0000404B | CERR_InvalidSet +|**X**| 0000404C | CERR_InvalidSave +|**X**| 0000404D | CERR_InvalidEthnologueCode +| | 0000804E | CERR_CannotCreateTempfile +|**X**| 0000404F | CERR_90FeatureOnly_IfSystemStores +| | 00004050 | CERR_IfSystemStore_NotFound +| | 00004051 | CERR_90FeatureOnly_SetSystemStores +| | 00004052 | CERR_SetSystemStore_NotFound +| | 00004053 | CERR_90FeatureOnlyVirtualKeyDictionary +| | 00004054 | CERR_NotSupportedInKeymanWebContext +| | 00004055 | CERR_NotSupportedInKeymanWebOutput +| | 00004056 | CERR_NotSupportedInKeymanWebStore +| | 00004057 | CERR_VirtualCharacterKeysNotSupportedInKeymanWeb +| | 00004058 | CERR_VirtualKeysNotValidForMnemonicLayouts +| | 00004059 | CERR_InvalidTouchLayoutFile +| | 0000405A | CERR_TouchLayoutInvalidIdentifier +| | 0000405B | CERR_InvalidKeyCode +|**X**| 0000405C | CERR_90FeatureOnlyLayoutFile +|**X**| 0000405D | CERR_90FeatureOnlyKeyboardVersion +|**X**| 0000405E | CERR_KeyboardVersionFormatInvalid +| | 0000405F | CERR_ContextExHasInvalidOffset +|**X**| 00004060 | CERR_90FeatureOnlyEmbedCSS +|**X**| 00004061 | CERR_90FeatureOnlyTargets +| | 00004062 | CERR_ContextAndIndexInvalidInMatchNomatch +| | 00004063 | CERR_140FeatureOnlyContextAndNotAnyWeb +|**X**| 00004064 | CERR_ExpansionMustFollowCharacterOrVKey +|**X**| 00004065 | CERR_VKeyExpansionMustBeFollowedByVKey +|**X**| 00004066 | CERR_CharacterExpansionMustBeFollowedByCharacter +|**X**| 00004067 | CERR_VKeyExpansionMustUseConsistentShift +|**X**| 00004068 | CERR_ExpansionMustBePositive +|**X**| 00004069 | CERR_CasedKeysMustContainOnlyVirtualKeys +|**X**| 0000406A | CERR_CasedKeysMustNotIncludeShiftStates +|**X**| 0000406B | CERR_CasedKeysNotSupportedWithMnemonicLayout +|**X**| 0000406C | CERR_CannotUseReadWriteGroupFromReadonlyGroup +| | 0000406D | CERR_StatementNotPermittedInReadonlyGroup +|**X**| 0000406E | CERR_OutputInReadonlyGroup +|**X**| 0000406F | CERR_NewContextGroupMustBeReadonly +|**X**| 00004070 | CERR_PostKeystrokeGroupMustBeReadonly +|**X**| 00004071 | CERR_DuplicateGroup +|**X**| 00004072 | CERR_DuplicateStore +|**X**| 00004073 | CERR_RepeatedBegin +|**X**| 000080C0 | CERR_BufferOverflow diff --git a/common/test/keyboards/invalid/source/CERR_400A_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_400A_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..0b7f2ffb0ad3bed4171714aa3780b49e7d5c158c --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_400A_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' +c ***** CERR_InvalidToken 0x0000400A ******************************** ++ [CTRL B10] > L'1234' +c ******************************************************************* ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' diff --git a/common/test/keyboards/invalid/source/CERR_400D_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_400D_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..ade9793ed428e853c7ccb122338987ab26fbf958 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_400D_balochi_phonetic.kmn @@ -0,0 +1,130 @@ + c ***** CERR_InvalidVersion 0x0000400D ***************************** +store(&VERSION) '127.0' +c ******************************************************************* +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_400E_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_400E_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..ced7892f0584f46db2fb7aecb5f358716f801392 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_400E_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + c ***** CERR_InvalidLanguageLine 0x0000400E ************************ +store(&LANGUAGE) 'abc123' +c ******************************************************************* +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4013_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4013_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..cd838e36826e9c77539658da95cad512dc20500e --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4013_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +c ***** CERR_InvalidStoreLine 0x00004013 *************************** +store(&VERSION '10.0' +c ****************************************************************** +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4015_k_014___groups_and_virtual_keys.kmn b/common/test/keyboards/invalid/source/CERR_4015_k_014___groups_and_virtual_keys.kmn new file mode 100644 index 0000000000000000000000000000000000000000..da26166e5c3b1707b580cfffc5210d5d9da2d4bd --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4015_k_014___groups_and_virtual_keys.kmn @@ -0,0 +1,30 @@ +store(&NAME) '014 - groups and virtual keys' +c Description: Tests multiple groups and virtual keys with mnemonic layout +c keys: [K_A][SHIFT K_2][K_A][LCTRL K_2][K_A] +c expected: \u03B1\u1FB0\u1FB1 + +store(&VERSION) '9.0' + +begin Unicode > use(UMain) + +store(&MnemonicLayout) "0" + +c ---------------------------------------------- + +group(UMain) using keys + + [K_A] > U+03B1 + +c ***** CERR_InvalidDeadkey 0x00004015 ****************************** + + [CTRL K_q] > deadkey('–') +c ******************************************************************* + + + [ALT K_2] > deadkey(MacronBug) + + [SHIFT K_2] > deadkey(BreveBug) + + match > use(DK1) + +c ---------------------------------------------- + +group(DK1) + deadkey(MacronBug) U+03B1 > U+1FB1 c won't work + deadkey(BreveBug) U+03B1 > U+1FB0 c works \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4016_k_014___groups_and_virtual_keys.kmn b/common/test/keyboards/invalid/source/CERR_4016_k_014___groups_and_virtual_keys.kmn new file mode 100644 index 0000000000000000000000000000000000000000..9a07e0b058d15ddb9a3cb1d210e6a3f60b53ca7c --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4016_k_014___groups_and_virtual_keys.kmn @@ -0,0 +1,29 @@ +store(&NAME) '014 - groups and virtual keys' +c Description: Tests multiple groups and virtual keys with mnemonic layout +c keys: [K_A][SHIFT K_2][K_A][LCTRL K_2][K_A] +c expected: \u03B1\u1FB0\u1FB1 + +store(&VERSION) '9.0' + +begin Unicode > use(UMain) + +store(&MnemonicLayout) "0" + +c ---------------------------------------------- + +group(UMain) using keys + + [K_A] > U+03B1 + + [CTRL K_2] > deadkey(MacronBug) + + [ALT K_2] > deadkey(MacronBug) + + [SHIFT K_2] > deadkey(BreveBug) + + match > use(DK1) + +c ---------------------------------------------- + +group(DK1) + deadkey(MacronBug) U+03B1 > U+1FB1 c won't work + + c ***** CERR_InvalidValue 0x00004016 ***************************** + deXadkey(BreveBug) U+03B1 > U+1FB0 c works +c ******************************************************************* \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4017_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4017_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..ddc33aeb05752fca68ef3e754acf260f9bb105a5 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4017_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.bmp' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' +c ***** CERR_ZeroLengthString 0x00004017 *************************** ++ [CTRL B10] > +c ****************************************************************** ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4019_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4019_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..48f978a1eb8e24ba1e45d7a80de5a67f51117552 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4019_balochi_phonetic.kmn @@ -0,0 +1,129 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +c ***** CERR_UnterminatedString 0x00004019 ************************* +store(&BITMAP)CERR__balochi_phonetic.ico' +c ****************************************************************** +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_401D_k_034___options_double_set_reset.kmn b/common/test/keyboards/invalid/source/CERR_401D_k_034___options_double_set_reset.kmn new file mode 100644 index 0000000000000000000000000000000000000000..31876eeeef42142fc7f5c0066b8859ce9952b610 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_401D_k_034___options_double_set_reset.kmn @@ -0,0 +1,22 @@ +store(&NAME) '034 - options double set reset' +c Description: Tests basic option rules with save reset+set+reset +c keys: [K_A][K_A] +c expected: foo.foo. +c context: +c option: foo=1 +c expected option: foo=1 + +store(&version) '10.0' + +store(foo) '0' + +begin Unicode > use(Main) + +group(Main) using keys + +c ***** CERR_StoreDoesNotExist 0x0000401D *********************************** +if(foo = '1') + 'a' > 'foo.' set(foo='2') reset(ffoo) set(foo='3') reset(foo) +c ******************************************************************* +if(foo = '2') + 'a' > 'bar.' +if(foo = '3') + 'a' > 'baz.' +if(foo = '0') + 'a' > 'no foo.' diff --git a/common/test/keyboards/invalid/source/CERR_4026_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4026_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..6fb2c649de3dd6b1990401ec62fb00a5f385a7bf --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4026_balochi_phonetic.kmn @@ -0,0 +1,17 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +c ***** CERR_GroupDoesNotExist 0x00004026 ************************** + +c ****************************************************************** \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4029_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4029_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..3d093c36d41c0a3283b4b3691ba1c7d058bebd41 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4029_balochi_phonetic.kmn @@ -0,0 +1,128 @@ +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +c ***** CERR_NoTokensFound 0x00004029 ******************************* +begin +c ******************************************************************* +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '§' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' diff --git a/common/test/keyboards/invalid/source/CERR_402B_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_402B_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..7da903abe354889807846d265c91abeaaf153a49 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_402B_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +c ***** CERR_LineTooLong 0x0000402B ******************************** +store(©RIGHT) '© 2017-2021 SIL InternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxInternationalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +c ****************************************************************** +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_402D_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_402D_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..37755739b9baf7d766330ebb8093a8b3aa25a8a3 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_402D_balochi_phonetic.kmn @@ -0,0 +1,129 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) +c ***** CERR_CodeInvalidInThisSection 0x0000402D ******************* + +c ****************************************************************** ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4031_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4031_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..b9b62c3a42a34402a09aa4d4c0ae811a4b42fd9d --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4031_balochi_phonetic.kmn @@ -0,0 +1,129 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +c ***** CERR_CannotReadBitmapFile 0x00004031 *********************** +store(&BITMAP) 'balochi_phonetic.ico' +c ****************************************************************** +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4034_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4034_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..c5c8306d37ab0d5ca250a37da110fce3aa9b0aa4 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4034_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +c ***** CERR_InvalidCharacter 0x00004034 *************************** +store(©RIGHT) '© 2012 U+1234 -2020 SIL International' +c ****************************************************************** +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4038_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4038_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..7e6eaedb1f9c2097f13854e21ccaa9e2a7d6731c --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4038_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' +c ***** CERR_CannotLoadIncludeFile 0x00004038 ********************** +store(&INCLUDECODES) 'XX.txt' +c ****************************************************************** +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4039_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4039_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..7eb9571a143603baa4ca1c4b912bccadf32f1fe7 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4039_balochi_phonetic.kmn @@ -0,0 +1,137 @@ +c ***** This test will produce XXXX Error: *************************** +c ***** 1) it will be marked as FAIL when run in kmcompxtest ******* +c ***** as a XXXXXXX non-existing ErrorNr (0x00040733) is specified ***** +c ******************************************************************store(&VERSION) '10.0' + +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +c ***** CERR_60FeatureOnly_EthnologueCode 0x00004039 **************** +store(&version) '3.0' +store(ÐNOLOGUECODE) 'eng' +c ******************************************************************* + +begin Unicode > use(main) + +group (main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '§' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' diff --git a/common/test/keyboards/invalid/source/CERR_403A_014_groups_and_virtual_keys.kmn b/common/test/keyboards/invalid/source/CERR_403A_014_groups_and_virtual_keys.kmn new file mode 100644 index 0000000000000000000000000000000000000000..43981238d7b594f6a4a3ce079a640958b82a25c0 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_403A_014_groups_and_virtual_keys.kmn @@ -0,0 +1,34 @@ +c RegressionTest: Multiple groups and virtual keys +c Font: Arial Unicode MS +c Encoding: Unicode +c Description: Tests multiple groups and virtual keys -- bug Ixxx +c Procedure: Press A, Shift+2, A, Ctrl+2, A +c AutoProc: K_A S+ K_2 S- K_A C+ K_2 C- K_A +c FinalOutput: U+03B1 U+1FB0 U+1FB1 + +c ***** CERR_60FeatureOnly_MnemonicLayout 0x0000403A **************** +store(&VERSION) '3.0' +c ******************************************************************* + +NAME "AltGr Deadkeys Test" + +begin Unicode > use(UMain) c Substitute UMain1 or UMain2 + +c ***** CERR_60FeatureOnly_MnemonicLayout 0x0000403A **************** +store(&MnemonicLayout) "1" +c ******************************************************************* + + +c ---------------------------------------------- +group(UMain) using keys + + ['a'] > U+03B1 + + [CTRL '2'] > deadkey(MacronBug) + + [ALT '2'] > deadkey(MacronBug) + + [SHIFT '2'] > deadkey(BreveBug) + match > use(DK1) + +c ---------------------------------------------- + +group(DK1) + deadkey(MacronBug) U+03B1 > U+1FB1 c won't work + deadkey(BreveBug) U+03B1 > U+1FB0 c works diff --git a/common/test/keyboards/invalid/source/CERR_403E_imsample.kmn b/common/test/keyboards/invalid/source/CERR_403E_imsample.kmn new file mode 100644 index 0000000000000000000000000000000000000000..93c90cfcea9ad0d78fc964fc2fc109306f3d7d77 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_403E_imsample.kmn @@ -0,0 +1,17 @@ +c ***** CERR_501FeatureOnly_Call 0x0000403E ************************* +store(&VERSION) '3.0' +c ******************************************************************* +store(&NAME) 'IMTest' +store(DLLFunction) "imsample.dll:DF" + +begin Unicode > use(main) + +group(main) using keys + +c ***** CERR_501FeatureOnly_Call 0x0000403E ************************* + ++ [K_BKSP] > call(DLLFunction) ++ [K_ESC] > call(DLLFunction) + +nomatch > call(DLLFunction) +c ******************************************************************* \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4040_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4040_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..4e6e7b41e3690d06de24114c98218bde2d3eae5e --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4040_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +c ***** CERR_InvalidSystemStore 0x00004040 ************************* +store(&NXXAME) 'Balochi Phonetic' +c ****************************************************************** +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4044_014_groups_and_virtual_keys.kmn b/common/test/keyboards/invalid/source/CERR_4044_014_groups_and_virtual_keys.kmn new file mode 100644 index 0000000000000000000000000000000000000000..42a0f87ee027286e4a584a14949226ade314d2e2 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4044_014_groups_and_virtual_keys.kmn @@ -0,0 +1,33 @@ +c RegressionTest: Multiple groups and virtual keys +c Font: Arial Unicode MS +c Encoding: Unicode +c Description: Tests multiple groups and virtual keys -- bug Ixxx +c Procedure: Press A, Shift+2, A, Ctrl+2, A +c AutoProc: K_A S+ K_2 S- K_A C+ K_2 C- K_A +c FinalOutput: U+03B1 U+1FB0 U+1FB1 + +c ***** CERR_501FeatureOnly_Call 0x0000403E ************************* +store(&VERSION) '3.0' +c ******************************************************************* + +NAME "AltGr Deadkeys Test" + +begin Unicode > use(UMain) c Substitute UMain1 or UMain2 + +store(&MnemonicLayout) "1" + +c ---------------------------------------------- +c ***** CERR_60FeatureOnly_VirtualCharKey 0x00004044 **************** +group(UMain) using keys + + ['a'] > U+03B1 + + [CTRL '2'] > deadkey(MacronBug) + + [ALT '2'] > deadkey(MacronBug) + + [SHIFT '2'] > deadkey(BreveBug) +c ******************************************************************* + match > use(DK1) + +c ---------------------------------------------- + +group(DK1) + deadkey(MacronBug) U+03B1 > U+1FB1 c won't work + deadkey(BreveBug) U+03B1 > U+1FB0 c works diff --git a/common/test/keyboards/invalid/source/CERR_4045_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4045_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..b50a62ced3d79c202444d2e78ee72fc87f39c853 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4045_balochi_phonetic.kmn @@ -0,0 +1,134 @@ +store(&VERSION) '10.0' + +c ***** CERR_VersionAlreadyIncluded 0x00004045 ****************************** +store(&VERSION) '110.0' +c ******************************************************************* + +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' diff --git a/common/test/keyboards/invalid/source/CERR_4046_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4046_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..69b4ce96f60b103118c13352af0b9026ca5cb67b --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4046_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +c ***** CERR_70FeatureOnly 0x00004046 ****************************** +store(&VERSION) '4.0' +c ****************************************************************** +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4047_k_022___options_with_preset.kmn b/common/test/keyboards/invalid/source/CERR_4047_k_022___options_with_preset.kmn new file mode 100644 index 0000000000000000000000000000000000000000..174a768ee55235664cf2add63c231a9e71b12fc0 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4047_k_022___options_with_preset.kmn @@ -0,0 +1,26 @@ +store(&NAME) '022 - options with preset' +c Description: Tests basic option rules with a preset supplied +c keys: [K_A][K_1][K_A][K_0][K_A] +c expected: foo.foo.no foo. +c context: +c option: foo=1 +c expected option: foo=0 +c saved option: foo=0 + +c ***** CERR_80FeatureOnly 0x00004047 ******************************* +store(&VERSION) '3.0' +c ******************************************************************* + +store(foo) '0' + +begin Unicode > use(Main) + +group(Main) using keys + +if(foo = '1') + 'a' > 'foo.' +if(foo = '0') + 'a' > 'no foo.' + +c ***** CERR_80FeatureOnly 0x00004047 ******************************* ++ '1' > set(foo = '1') save(foo) ++ '0' > set(foo = '0') save(foo) +c ******************************************************************* \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4049_k_022___options_with_preset.kmn b/common/test/keyboards/invalid/source/CERR_4049_k_022___options_with_preset.kmn new file mode 100644 index 0000000000000000000000000000000000000000..ea423987a4fe8efe39549d7e2ad069fe322bdb61 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4049_k_022___options_with_preset.kmn @@ -0,0 +1,24 @@ +store(&NAME) '022 - options with preset' +c Description: Tests basic option rules with a preset supplied +c keys: [K_A][K_1][K_A][K_0][K_A] +c expected: foo.foo.no foo. +c context: +c option: foo=1 +c expected option: foo=0 +c saved option: foo=0 + +store(&VERSION) '8.0' + +store(foo) '0' + +begin Unicode > use(Main) + +group(Main) using keys + +c ***** CERR_InvalidIf 0x00004049 *********************************** +if(foo '1') + 'a' > 'foo.' +c ******************************************************************* +if(foo = '0') + 'a' > 'no foo.' + ++ '1' > set(foo = '1') save(foo) ++ '0' > set(foo = '0') save(foo) \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_404A_k_025___options_with_reset.kmn b/common/test/keyboards/invalid/source/CERR_404A_k_025___options_with_reset.kmn new file mode 100644 index 0000000000000000000000000000000000000000..9dea1a51e4a62961e7da2b88427758dcd5eca10b --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_404A_k_025___options_with_reset.kmn @@ -0,0 +1,23 @@ +store(&NAME) '025 - options with reset' +c Description: Tests basic option rules with reset +c keys: [K_A][K_1][K_A][K_0][K_A][K_3] +c expected: foo.foo.no foo. +c context: +c option: foo=1 +c expected option: foo=1 + +store(&version) '10.0' + +store(foo) '0' + +begin Unicode > use(Main) + +group(Main) using keys + +if(foo = '1') + 'a' > 'foo.' +if(foo = '0') + 'a' > 'no foo.' ++ '1' > set(foo = '1') ++ '0' > set(foo = '0') +c ***** CERR_InvalidReset 0x0000404A ******************************** ++ '3' > reset +c ******************************************************************* diff --git a/common/test/keyboards/invalid/source/CERR_404B_k_025___options_with_reset.kmn b/common/test/keyboards/invalid/source/CERR_404B_k_025___options_with_reset.kmn new file mode 100644 index 0000000000000000000000000000000000000000..70b534fc7ec6079a419d3bdad044d974bb2947b2 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_404B_k_025___options_with_reset.kmn @@ -0,0 +1,25 @@ +store(&NAME) '025 - options with reset' +c Description: Tests basic option rules with reset +c keys: [K_A][K_1][K_A][K_0][K_A][K_3] +c expected: foo.foo.no foo. +c context: +c option: foo=1 +c expected option: foo=1 + +store(&version) '10.0' + +store(foo) '0' + +begin Unicode > use(Main) + +group(Main) using keys + +if(foo = '1') + 'a' > 'foo.' +if(foo = '0') + 'a' > 'no foo.' + +c ***** CERR_InvalidReset 0x0000404B ******************************** ++ '1' > set( ++ '0' > set +c ******************************************************************* + ++ '3' > reset(foo) diff --git a/common/test/keyboards/invalid/source/CERR_404C_k_023___options_with_save.kmn b/common/test/keyboards/invalid/source/CERR_404C_k_023___options_with_save.kmn new file mode 100644 index 0000000000000000000000000000000000000000..a160ace737fe6e66a26c221582ba17e63a272981 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_404C_k_023___options_with_save.kmn @@ -0,0 +1,23 @@ +store(&NAME) '023 - options with save' +c Description: Tests basic option rules with save +c keys: [K_A][K_1][K_A][K_0][K_A][K_2] +c expected: no foo.foo.no foo. +c context: +c expected option: foo=0 +c saved option: foo=0 + +store(&version) '10.0' + +store(foo) '0' + +begin Unicode > use(Main) + +group(Main) using keys + +if(foo = '1') + 'a' > 'foo.' +if(foo = '0') + 'a' > 'no foo.' ++ '1' > set(foo = '1') ++ '0' > set(foo = '0') +c ***** CERR_InvalidSave 0x0000404C ********************************* ++ '2' > save +c ******************************************************************* diff --git a/common/test/keyboards/invalid/source/CERR_404D_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_404D_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..7aadf5567236c4ba363f4c10fd5131b7602c996e --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_404D_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' +c ***** CERR_InvalidEthnologueCode 0x0000404D ********************** +store(&EthnologueCode) "xxxx" +c ****************************************************************** +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_404F_k_026___system_stores.kmn b/common/test/keyboards/invalid/source/CERR_404F_k_026___system_stores.kmn new file mode 100644 index 0000000000000000000000000000000000000000..e336ac5d789c0ac505e235998838905724c58ab7 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_404F_k_026___system_stores.kmn @@ -0,0 +1,29 @@ +store(&NAME) '026 - system stores' +c Description: Tests platform and baselayout system store rules +c keys: [K_1][K_2][K_3][K_4][K_A][K_B] +c expected: windows.desktop.hardware.native.en-US.kbdus.dll. +c context: +c (default) option: &platform=windows desktop hardware native <-- ignored by test +c (default) option: &baseLayout=kbdus.dll <-- ignored by test +c (default) option: &baseLayoutAlt=en-US <-- ignored by test + +c ***** CERR_90FeatureOnly_IfSystemStores 0x0000404F **************** +store(&version) '3.0' +c ******************************************************************* + +store(digit) '1234567890' +store(letter) 'abcdefghij' + +begin Unicode > use(Main) + +group(Main) using keys + +platform('windows') + '1' > 'windows.' +platform('desktop') + '2' > 'desktop.' +platform('hardware') + '3' > 'hardware.' +platform('native') + '4' > 'native.' ++ any(digit) > 'platform-fail.' + +baselayout('en-US') + 'a' > 'en-US.' +baselayout('kbdus.dll') + 'b' > 'kbdus.dll.' ++ any(letter) > 'baselayout-fail.' diff --git a/common/test/keyboards/invalid/source/CERR_405C_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_405C_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..ad777616033d925f4feec7502e1b70666fafeafd --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_405C_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +c ***** CERR_90FeatureOnlyLayoutFile 0x0000405C ******************** +store(&VERSION) '4.0' +c ****************************************************************** +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_405D_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_405D_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..e1224961ddd0c80fffdcb53419ea3159c6212793 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_405D_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +c ***** CERR_90FeatureOnlyKeyboardVersion 0x0000405D *************** +store(&VERSION) '4.0' +c ****************************************************************** +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_405E_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_405E_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..c255c0f5e7c8ca1c3a58cab350ab2793c886d5b8 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_405E_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +c ***** CERR_KeyboardVersionFormatInvalid 0x0000405E *************** +store(&KEYBOARDVERSION) 'abc' +c ****************************************************************** +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4060_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4060_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..6fc5ebe1ae72fa40af46af5edef5583559953d51 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4060_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +store(&VERSION) '4.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' +c ***** CERR_90FeatureOnlyEmbedCSS 0x00004060 ********************** +store(&KMW_EMBEDCSS) 'naijatype.css' +c ****************************************************************** +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4061_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4061_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..47b224d2c6a281ef1ca6c84df6f3b9c51eb79317 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4061_balochi_phonetic.kmn @@ -0,0 +1,130 @@ +c ***** CERR_90FeatureOnlyTargets 0x00004061 *********************** +store(&VERSION) '4.0' +c ****************************************************************** +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' \ No newline at end of file diff --git a/common/test/keyboards/invalid/source/CERR_4064_caps_lock_layer_3620.kmn b/common/test/keyboards/invalid/source/CERR_4064_caps_lock_layer_3620.kmn new file mode 100644 index 0000000000000000000000000000000000000000..dbc3b65a80fd5e6a5305221ba5e811c99da7ab76 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4064_caps_lock_layer_3620.kmn @@ -0,0 +1,22 @@ +c caps_lock_layer_3620 generated from template at 2021-11-30 14:58:52 +c with name "Caps Lock Layer 3620" +store(&VERSION) '10.0' +store(&NAME) 'Caps Lock Layer 3620' +store(©RIGHT) '©' +store(&KEYBOARDVERSION) '1.0' +store(&TARGETS) 'any' +store(&VISUALKEYBOARD) 'caps_lock_layer_3620.kvks' +store(&LAYOUTFILE) 'caps_lock_layer_3620.keyman-touch-layout' + +begin Unicode > use(main) + +store(key) [K_A] .. [K_Z] [SHIFT K_A] .. [SHIFT K_Z] +c ***** CERR_ExpansionMustFollowCharacterOrVKey 0x00004064 ********** +store(out) .. 'z' 'A' .. 'Z' +c ******************************************************************* +store(&CasedKeys) [K_A] .. [K_Z] + +group(main) using keys + ++ any(key) > index(out, 1) + diff --git a/common/test/keyboards/invalid/source/CERR_4065_test_expansion_invalid.kmn b/common/test/keyboards/invalid/source/CERR_4065_test_expansion_invalid.kmn new file mode 100644 index 0000000000000000000000000000000000000000..b721946537f14c4f9ce0e21cd2b72303ab1b404c --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4065_test_expansion_invalid.kmn @@ -0,0 +1,34 @@ +c This file tests that invalid expansions are caught +store(&NAME) 'Test Invalid Expansions' +begin Unicode > use(main) + +group(main) using keys + +c Backward ranges + +store(char_range_backward) 'c' .. 'a' +store(key_range_backward) [K_E] .. [K_A] + +store(char_range_empty) 'c' .. 'c' +store(key_range_empty) [K_E] .. [K_E] + +c Incomplete ranges + +store(range_open) .. +store(char_range_open_end) 'a' .. +store(char_range_open_start) .. 'z' + +store(key_range_open_end) [K_A] .. +store(key_range_open_start) .. [K_Z] + +c Inconsistent ranges + +store(char_range_to_key) 'a' .. [K_Z] +store(key_range_to_char) [K_A] .. 'z' + +store(char_range_to_statement) 'a' .. nul +store(key_range_to_statement) [K_A] .. nul +store(char_range_from_statement) nul .. 'a' +store(key_range_from_statement) nul .. [K_A] + +store(key_range_shift_inconsistent) [SHIFT K_A] .. [K_Z] diff --git a/common/test/keyboards/invalid/source/CERR_4066_test_expansion_invalid.kmn b/common/test/keyboards/invalid/source/CERR_4066_test_expansion_invalid.kmn new file mode 100644 index 0000000000000000000000000000000000000000..b721946537f14c4f9ce0e21cd2b72303ab1b404c --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4066_test_expansion_invalid.kmn @@ -0,0 +1,34 @@ +c This file tests that invalid expansions are caught +store(&NAME) 'Test Invalid Expansions' +begin Unicode > use(main) + +group(main) using keys + +c Backward ranges + +store(char_range_backward) 'c' .. 'a' +store(key_range_backward) [K_E] .. [K_A] + +store(char_range_empty) 'c' .. 'c' +store(key_range_empty) [K_E] .. [K_E] + +c Incomplete ranges + +store(range_open) .. +store(char_range_open_end) 'a' .. +store(char_range_open_start) .. 'z' + +store(key_range_open_end) [K_A] .. +store(key_range_open_start) .. [K_Z] + +c Inconsistent ranges + +store(char_range_to_key) 'a' .. [K_Z] +store(key_range_to_char) [K_A] .. 'z' + +store(char_range_to_statement) 'a' .. nul +store(key_range_to_statement) [K_A] .. nul +store(char_range_from_statement) nul .. 'a' +store(key_range_from_statement) nul .. [K_A] + +store(key_range_shift_inconsistent) [SHIFT K_A] .. [K_Z] diff --git a/common/test/keyboards/invalid/source/CERR_4067_test_expansion_invalid.kmn b/common/test/keyboards/invalid/source/CERR_4067_test_expansion_invalid.kmn new file mode 100644 index 0000000000000000000000000000000000000000..b721946537f14c4f9ce0e21cd2b72303ab1b404c --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4067_test_expansion_invalid.kmn @@ -0,0 +1,34 @@ +c This file tests that invalid expansions are caught +store(&NAME) 'Test Invalid Expansions' +begin Unicode > use(main) + +group(main) using keys + +c Backward ranges + +store(char_range_backward) 'c' .. 'a' +store(key_range_backward) [K_E] .. [K_A] + +store(char_range_empty) 'c' .. 'c' +store(key_range_empty) [K_E] .. [K_E] + +c Incomplete ranges + +store(range_open) .. +store(char_range_open_end) 'a' .. +store(char_range_open_start) .. 'z' + +store(key_range_open_end) [K_A] .. +store(key_range_open_start) .. [K_Z] + +c Inconsistent ranges + +store(char_range_to_key) 'a' .. [K_Z] +store(key_range_to_char) [K_A] .. 'z' + +store(char_range_to_statement) 'a' .. nul +store(key_range_to_statement) [K_A] .. nul +store(char_range_from_statement) nul .. 'a' +store(key_range_from_statement) nul .. [K_A] + +store(key_range_shift_inconsistent) [SHIFT K_A] .. [K_Z] diff --git a/common/test/keyboards/invalid/source/CERR_4068_test_expansion_invalid.kmn b/common/test/keyboards/invalid/source/CERR_4068_test_expansion_invalid.kmn new file mode 100644 index 0000000000000000000000000000000000000000..b721946537f14c4f9ce0e21cd2b72303ab1b404c --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4068_test_expansion_invalid.kmn @@ -0,0 +1,34 @@ +c This file tests that invalid expansions are caught +store(&NAME) 'Test Invalid Expansions' +begin Unicode > use(main) + +group(main) using keys + +c Backward ranges + +store(char_range_backward) 'c' .. 'a' +store(key_range_backward) [K_E] .. [K_A] + +store(char_range_empty) 'c' .. 'c' +store(key_range_empty) [K_E] .. [K_E] + +c Incomplete ranges + +store(range_open) .. +store(char_range_open_end) 'a' .. +store(char_range_open_start) .. 'z' + +store(key_range_open_end) [K_A] .. +store(key_range_open_start) .. [K_Z] + +c Inconsistent ranges + +store(char_range_to_key) 'a' .. [K_Z] +store(key_range_to_char) [K_A] .. 'z' + +store(char_range_to_statement) 'a' .. nul +store(key_range_to_statement) [K_A] .. nul +store(char_range_from_statement) nul .. 'a' +store(key_range_from_statement) nul .. [K_A] + +store(key_range_shift_inconsistent) [SHIFT K_A] .. [K_Z] diff --git a/common/test/keyboards/invalid/source/CERR_4069_test_casedkeys_invalid_1.kmn b/common/test/keyboards/invalid/source/CERR_4069_test_casedkeys_invalid_1.kmn new file mode 100644 index 0000000000000000000000000000000000000000..8bc65cced65cdb06504bd374dc707866e88155cc --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4069_test_casedkeys_invalid_1.kmn @@ -0,0 +1,10 @@ +c Tests cased keys - invalid codes +store(&NAME) 'Test &CasedKeys' +begin Unicode > use(main) + +group(main) using keys + +store(&CasedKeys) U+1000 + ++ [K_A] > 'aaah' ++ [SHIFT K_A] > 'AAAH' diff --git a/common/test/keyboards/invalid/source/CERR_406A_test_casedkeys_invalid_2.kmn b/common/test/keyboards/invalid/source/CERR_406A_test_casedkeys_invalid_2.kmn new file mode 100644 index 0000000000000000000000000000000000000000..508466c07e53ddddd21139e25eaf115d3513dff3 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_406A_test_casedkeys_invalid_2.kmn @@ -0,0 +1,10 @@ +c Tests cased keys - invalid codes +store(&NAME) 'Test &CasedKeys' +begin Unicode > use(main) + +group(main) using keys + +store(&CasedKeys) [SHIFT K_1] + ++ [K_A] > 'aaah' ++ [SHIFT K_A] > 'AAAH' diff --git a/common/test/keyboards/invalid/source/CERR_406B_test_casedkeys_mnemonic_1.kmn b/common/test/keyboards/invalid/source/CERR_406B_test_casedkeys_mnemonic_1.kmn new file mode 100644 index 0000000000000000000000000000000000000000..40b0bbb9668283bea355f6babeb7dea0a5936dd3 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_406B_test_casedkeys_mnemonic_1.kmn @@ -0,0 +1,11 @@ +c Tests cased keys - invalid with mnemonic layout +store(&NAME) 'Test &CasedKeys' +store(&mnemoniclayout) '1' +begin Unicode > use(main) + +group(main) using keys + +store(&CasedKeys) [K_A] [K_E] [K_I] [K_O] [K_U] [K_1] .. [K_4] + ++ [K_A] > 'aaah' ++ [SHIFT K_A] > 'AAAH' diff --git a/common/test/keyboards/invalid/source/CERR_406C_test_5963_readonlygroup_usenonreadonly.kmn b/common/test/keyboards/invalid/source/CERR_406C_test_5963_readonlygroup_usenonreadonly.kmn new file mode 100644 index 0000000000000000000000000000000000000000..8ced461fc755ab4db76b43c9b5728d529b29b4ae --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_406C_test_5963_readonlygroup_usenonreadonly.kmn @@ -0,0 +1,12 @@ +c should fail to compile, readonly group uses() non-readonly group + +begin Unicode > use(main) + +group(main) using keys + +group(foo) readonly + +'a' > use(bar) + +group(bar) + diff --git a/common/test/keyboards/invalid/source/CERR_406E_test_5963_readonlygroup_misplacedcontext.kmn b/common/test/keyboards/invalid/source/CERR_406E_test_5963_readonlygroup_misplacedcontext.kmn new file mode 100644 index 0000000000000000000000000000000000000000..251a3d1033c7fa2593ed684cb35e8138db89fd64 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_406E_test_5963_readonlygroup_misplacedcontext.kmn @@ -0,0 +1,11 @@ +c Should fail to compile, `context` must be omitted or first statement in output + +begin Unicode > use(main) + +group(main) using keys + +group(foo) readonly + +'a' > use(bar) context + +group(bar) readonly diff --git a/common/test/keyboards/invalid/source/CERR_406F_test_5963_newcontext_2.kmn b/common/test/keyboards/invalid/source/CERR_406F_test_5963_newcontext_2.kmn new file mode 100644 index 0000000000000000000000000000000000000000..a2916de43a66b86bd2cdf3f158fca3a7da887094 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_406F_test_5963_newcontext_2.kmn @@ -0,0 +1,9 @@ +c Should fail to compile, group is not readonly + +begin Unicode > use(main) +begin NewContext > use(NewContext) + +group(NewContext) + +group(main) using keys + diff --git a/common/test/keyboards/invalid/source/CERR_4070_test_5963_postkeystroke_2.kmn b/common/test/keyboards/invalid/source/CERR_4070_test_5963_postkeystroke_2.kmn new file mode 100644 index 0000000000000000000000000000000000000000..12bb3661501c9feb86cd059ac063b5423379cc1f --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4070_test_5963_postkeystroke_2.kmn @@ -0,0 +1,8 @@ +c Should fail to compile, group is not readonly + +begin Unicode > use(main) +begin PostKeystroke > use(PostKeystroke) + +group(PostKeystroke) + +group(main) using keys diff --git a/common/test/keyboards/invalid/source/CERR_4071_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4071_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..68a8a542469eed6765306ba3e326bbf5384e7669 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4071_balochi_phonetic.kmn @@ -0,0 +1,131 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +c ***** CERR_DuplicateGroup 0x00004071 ****************************** +group(main) using keys +c ******************************************************************* +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' diff --git a/common/test/keyboards/invalid/source/CERR_4072_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4072_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..ca9f15d3f3a6f1afa98285e1b6944216b19538bd --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4072_balochi_phonetic.kmn @@ -0,0 +1,133 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' + +c ***** DuplicateStore 0x00004072 *********************************** +store(©RIGHT) '© ABC' +c ******************************************************************* + +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' diff --git a/common/test/keyboards/invalid/source/CERR_4073_balochi_phonetic.kmn b/common/test/keyboards/invalid/source/CERR_4073_balochi_phonetic.kmn new file mode 100644 index 0000000000000000000000000000000000000000..9483a2196dc4777083e3150d075fc34d983a6965 --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_4073_balochi_phonetic.kmn @@ -0,0 +1,132 @@ +store(&VERSION) '10.0' +store(&NAME) 'Balochi Phonetic' +store(&TARGETS) 'any' +store(&KMW_RTL) '1' +store(&LAYOUTFILE) 'balochi_phonetic.keyman-touch-layout' +store(&KEYBOARDVERSION) '1.4.2' +store(©RIGHT) '© 2017-2021 SIL International' +store(&MESSAGE) 'The Balochi Phonetic keyboard is distributed under The MIT License (MIT).' +store(&KMW_HELPTEXT) 'This is a phonetically organized Balochi keyboard.' +store(&VISUALKEYBOARD) 'balochi_phonetic.kvks' +store(&BITMAP) 'CERR__balochi_phonetic.ico' + +begin Unicode > use(main) + +c ***** CERR_RepeatedBegin 0x00004073 ******************************* +begin Unicode > use(main) +c ******************************************************************* + +group(main) using keys ++ [CTRL B08] > '‎' ++ [CTRL B09] > 'â€' ++ [CTRL B10] > '–' ++ [SHIFT CTRL E11] > '“' ++ [SHIFT CTRL E12] > 'â€' ++ [CTRL E11] > '‘' ++ [CTRL E12] > '’' ++ [CTRL K_K] > 'Ø¡' ++ [CTRL K_D] > 'ذ' ++ [K_EQUAL] > '=' ++ [SHIFT K_8] > '*' ++ [SHIFT K_7] > '&' ++ [SHIFT K_5] > '%' ++ [SHIFT K_4] > '$' ++ [SHIFT K_3] > '#' ++ [SHIFT K_2] > '@' ++ [SHIFT K_1] > '!' ++ [SHIFT K_N] > 'Úº' ++ [K_BKSLASH] > 'Û”' ++ [K_LBRKT] > ']' ++ [K_RBRKT] > '[' ++ [K_F] > 'ÙŽ' ++ [K_V] > 'Ù' ++ [K_X] > 'Ø´' ++ [SHIFT K_H] > 'Ø­' ++ [SHIFT K_G] > 'ص' ++ [SHIFT K_Y] > 'ÙŠ' ++ [CTRL K_0] > 'Û°' ++ [CTRL K_9] > 'Û¹' ++ [CTRL K_8] > 'Û¸' ++ [CTRL K_7] > 'Û·' ++ [CTRL K_6] > 'Û¶' ++ [CTRL K_5] > 'Ûµ' ++ [CTRL K_4] > 'Û´' ++ [CTRL K_3] > 'Û³' ++ [CTRL K_2] > 'Û²' ++ [CTRL K_1] > 'Û±' ++ [K_SLASH] > '/' ++ [K_HYPHEN] > '-' ++ [SHIFT K_COLON] > ':' ++ [SHIFT K_QUOTE] > '"' ++ [K_QUOTE] > U+0027 ++ [K_O] > 'Ù' ++ [SHIFT K_O] > 'Ù’' ++ [K_BKQUOTE] > 'Ø¡' ++ [SHIFT K_W] > 'Ø£' ++ [SHIFT K_P] > 'Ù‘' ++ [SHIFT K_BKQUOTE] > 'Ù”' ++ [SHIFT K_J] > 'ض' ++ [SHIFT K_9] > ')' ++ [SHIFT K_RBRKT] > '{' ++ [SHIFT K_LBRKT] > '}' ++ [SHIFT K_0] > '(' ++ [SHIFT K_SLASH] > 'ØŸ' ++ [SHIFT K_K] > 'ع' ++ [SHIFT K_EQUAL] > '«' ++ [SHIFT K_HYPHEN] > '»' ++ [SHIFT K_I] > 'Ù‹' + ++ [SHIFT K_PERIOD] > '‹' ++ [SHIFT K_COMMA] > '›' ++ [SHIFT K_L] > 'Ù€' ++ [SHIFT K_U] > 'Û€' ++ [SHIFT K_B] > 'Ø©' ++ [SHIFT K_M] > 'غ' ++ [SHIFT K_F] > 'Ù' ++ [SHIFT K_E] > 'Û“' ++ [SHIFT K_Q] > 'Ù‚' ++ [K_0] > '0' ++ [K_9] > '9' ++ [K_8] > '8' ++ [K_7] > '7' ++ [K_6] > '6' ++ [K_5] > '5' ++ [K_4] > '4' ++ [K_3] > '3' ++ [K_2] > '2' ++ [K_1] > '1' ++ [K_I] > 'ÛŽ' ++ [SHIFT K_D] > 'Úˆ' ++ [K_G] > 'Ú¯' ++ [K_U] > 'Û†' ++ [SHIFT K_R] > 'Ú‘' ++ [SHIFT K_6] > '‌' ++ [SHIFT K_T] > 'Ù¹' ++ [SHIFT K_V] > 'ظ' ++ [SHIFT K_C] > 'Ø·' ++ [SHIFT K_X] > 'Ø®' ++ [SHIFT K_Z] > 'Ú˜' ++ [SHIFT K_S] > 'Ø«' ++ [SHIFT K_A] > 'Ø¢' ++ [K_PERIOD] > '.' ++ [K_COMMA] > 'ØŒ' ++ [K_M] > 'Ù…' ++ [K_N] > 'Ù†' ++ [K_B] > 'ب' ++ [K_C] > 'Ú†' ++ [K_Z] > 'ز' ++ [K_P] > 'Ù¾' ++ [K_Y] > 'ÛŒ' ++ [K_T] > 'ت' ++ [K_R] > 'ر' ++ [K_E] > 'Û’' ++ [K_W] > 'Ùˆ' ++ [K_Q] > 'ئ' ++ [K_COLON] > 'Ø›' ++ [K_L] > 'Ù„' ++ [K_K] > 'Ú©' ++ [K_J] > 'ج' ++ [K_H] > 'Ù‡' ++ [K_D] > 'د' ++ [K_S] > 'س' ++ [K_A] > 'ا' diff --git a/common/test/keyboards/invalid/source/CERR_80C0_test_expansion_absurd.kmn b/common/test/keyboards/invalid/source/CERR_80C0_test_expansion_absurd.kmn new file mode 100644 index 0000000000000000000000000000000000000000..905093bc87ba33ce886f45e6428289af0d0e281d --- /dev/null +++ b/common/test/keyboards/invalid/source/CERR_80C0_test_expansion_absurd.kmn @@ -0,0 +1,7 @@ +c This file tests absurdly long expansions +store(&NAME) 'Test Expansions' +begin Unicode > use(main) + +group(main) using keys + +store(schar_range) U+0020 .. U+10FFFF diff --git a/common/test/keyboards/invalid/source/CERR__balochi_phonetic.ico b/common/test/keyboards/invalid/source/CERR__balochi_phonetic.ico new file mode 100644 index 0000000000000000000000000000000000000000..3fc6a224294396c55920dba4f44210059df71bef Binary files /dev/null and b/common/test/keyboards/invalid/source/CERR__balochi_phonetic.ico differ diff --git a/common/test/resources/keyboards/options_with_save.js b/common/test/resources/keyboards/options_with_save.js index 301ae1c673b602780a26ed0c71215fae44ccfbf7..8252b5166041aeea7d27f8100e72267fd269543b 100644 --- a/common/test/resources/keyboards/options_with_save.js +++ b/common/test/resources/keyboards/options_with_save.js @@ -1,4 +1,4 @@ -// Original source may be found within the repo at /core/tests/unit/kmx/ as #023. +// Original source may be found within the repo at /common/tests/keyboards/baseline/k_023___options_with_save.kmn if(typeof keyman === 'undefined') { console.log('Keyboard requires KeymanWeb 10.0 or later'); diff --git a/common/web/keyboard-processor/src/index.ts b/common/web/keyboard-processor/src/index.ts index 8c60ae3f3939e1151408ee4bf703bdd291df7448..0464d2cd9c375fd847c528dda9f733a882233cc3 100644 --- a/common/web/keyboard-processor/src/index.ts +++ b/common/web/keyboard-processor/src/index.ts @@ -3,7 +3,7 @@ export * from "./keyboards/defaultLayouts.js"; export { default as Keyboard } from "./keyboards/keyboard.js"; export * from "./keyboards/keyboard.js"; export { KeyboardHarness, KeyboardKeymanGlobal, MinimalCodesInterface, MinimalKeymanGlobal } from "./keyboards/keyboardHarness.js"; -export { default as KeyboardLoaderBase } from "./keyboards/keyboardLoaderBase.js"; +export { default as KeyboardLoaderBase, KeyboardLoadErrorBuilder } from "./keyboards/keyboardLoaderBase.js"; export { CloudKeyboardFont, internalizeFont, diff --git a/common/web/keyboard-processor/src/keyboards/keyboardLoaderBase.ts b/common/web/keyboard-processor/src/keyboards/keyboardLoaderBase.ts index 2595f37db6cd7479f8939c4a479782040fd9ecd4..426ac15b81177a0e9571329cd395019447d20c28 100644 --- a/common/web/keyboard-processor/src/keyboards/keyboardLoaderBase.ts +++ b/common/web/keyboard-processor/src/keyboards/keyboardLoaderBase.ts @@ -2,6 +2,67 @@ import Keyboard from "./keyboard.js"; import { KeyboardHarness } from "./keyboardHarness.js"; import KeyboardProperties from "./keyboardProperties.js"; +type KeyboardStub = KeyboardProperties & { filename: string }; + +/** + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause + * + * While TS doesn't yet recognize it as a property of error, recent versions of JS define it. + * So, we should obviously conform to that spec, even if older versions of JS won't expect it + * to exist. + */ +type ErrorWithCause = Error & { cause?: Error }; + +export interface KeyboardLoadErrorBuilder { + scriptError(err?: Error); + missingError(err: Error); +} + +const buildAndFinalizeError = (msg: string, err?: Error): ErrorWithCause => { + const builtError: ErrorWithCause = new Error(msg); + builtError.cause = err; + + return builtError; +} + +class UriBasedErrorBuilder implements KeyboardLoadErrorBuilder { + readonly uri: string; + + constructor(uri: string) { + this.uri = uri; + } + + missingError(err: Error) { + const msg = `Cannot find the keyboard at ${this.uri}.`; + return buildAndFinalizeError(msg, err); + } + + scriptError(err: Error) { + const msg = `Error registering the keyboard script at ${this.uri}; it may contain an error.`; + return buildAndFinalizeError(msg, err); + } +} + +class StubBasedErrorBuilder implements KeyboardLoadErrorBuilder { + readonly stub: KeyboardStub; + + constructor(stub: KeyboardStub) { + this.stub = stub; + } + + missingError(err: Error) { + const stub = this.stub; + const msg = `Cannot find the ${stub.name} keyboard for ${stub.langName} at ${stub.filename}.`; + return buildAndFinalizeError(msg, err); + } + + scriptError(err: Error) { + const stub = this.stub; + const msg = `Error registering the ${stub.name} keyboard for ${stub.langName}; keyboard script at ${stub.filename} may contain an error.`; + return buildAndFinalizeError(msg, err); + } +} + export default abstract class KeyboardLoaderBase { private _harness: KeyboardHarness; @@ -15,53 +76,21 @@ export default abstract class KeyboardLoaderBase { public loadKeyboardFromPath(uri: string): Promise { this.harness.install(); - const promise = this.loadKeyboardInternal(uri); + const promise = this.loadKeyboardInternal(uri, new UriBasedErrorBuilder(uri)); return promise; } - public loadKeyboardFromStub(stub: KeyboardProperties & { filename: string }) { + public loadKeyboardFromStub(stub: KeyboardStub) { this.harness.install(); - let promise = this.loadKeyboardInternal(stub.filename, stub.id); - - promise = promise.catch((err: Error) => { - if(err == KeyboardLoaderBase.scriptErrorMessage(stub.filename)) { - // Enhance the error message. - err.message = KeyboardLoaderBase.scriptErrorMessage(stub); - } else if(err == KeyboardLoaderBase.missingErrorMessage(stub.filename)) { - // Same thing here. - err.message = KeyboardLoaderBase.scriptErrorMessage(stub); - } - - throw err; - }) + let promise = this.loadKeyboardInternal(stub.filename, new StubBasedErrorBuilder(stub), stub.id); return promise; } - protected abstract loadKeyboardInternal(uri: string, id?: string): Promise; - - protected static scriptErrorMessage(uri: string); - protected static scriptErrorMessage(metadata: KeyboardProperties & { filename: string }); - protected static scriptErrorMessage(arg: string | (KeyboardProperties & { filename: string })) { - if(typeof arg == "string") { - const uri = arg; - return `Error registering the keyboard script at ${uri}; it may contain an error.` - } else { - const stub = arg; - return `Error registering the ${stub.name} keyboard for ${stub.langName}; keyboard script at ${stub.filename} may contain an error.` - } - } - - protected static missingErrorMessage(uri: string); - protected static missingErrorMessage(metadata: KeyboardProperties & { filename: string }); - protected static missingErrorMessage(arg: string | (KeyboardProperties & { filename: string })) { - if(typeof arg == "string") { - const uri = arg; - return `Cannot find the keyboard at ${uri}.` - } else { - const stub = arg; - return `Cannot find the ${stub.name} keyboard for ${stub.langName} at ${stub.filename}.`; - } - } + protected abstract loadKeyboardInternal( + uri: string, + errorBuilder: KeyboardLoadErrorBuilder, + id?: string + ): Promise; } \ No newline at end of file diff --git a/common/web/keyboard-processor/src/keyboards/loaders/domKeyboardLoader.ts b/common/web/keyboard-processor/src/keyboards/loaders/domKeyboardLoader.ts index d753d37af9e21c86f8d239cce6dfee29e6b033de..ea7447d8f70d644ba4745a204326ac90d883055d 100644 --- a/common/web/keyboard-processor/src/keyboards/loaders/domKeyboardLoader.ts +++ b/common/web/keyboard-processor/src/keyboards/loaders/domKeyboardLoader.ts @@ -2,7 +2,7 @@ /// -import { Keyboard, KeyboardHarness, KeyboardLoaderBase, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor'; +import { Keyboard, KeyboardHarness, KeyboardLoaderBase, KeyboardLoadErrorBuilder, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor'; import { ManagedPromise } from '@keymanapp/web-utils'; @@ -28,7 +28,11 @@ export class DOMKeyboardLoader extends KeyboardLoaderBase { this.performCacheBusting = cacheBust || false; } - protected loadKeyboardInternal(uri: string, id?: string): Promise { + protected loadKeyboardInternal( + uri: string, + errorBuilder: KeyboardLoadErrorBuilder, + id?: string + ): Promise { const promise = new ManagedPromise(); if(this.performCacheBusting) { @@ -42,8 +46,8 @@ export class DOMKeyboardLoader extends KeyboardLoaderBase { script.id = id; } document.head.appendChild(script); - script.onerror = () => { - promise.reject(new Error(KeyboardLoaderBase.missingErrorMessage(uri))); + script.onerror = (err) => { + promise.reject(errorBuilder.missingError(err)); } script.onload = () => { if(this.harness.loadedKeyboard) { @@ -51,7 +55,7 @@ export class DOMKeyboardLoader extends KeyboardLoaderBase { this.harness.loadedKeyboard = null; promise.resolve(keyboard); } else { - promise.reject(new Error(KeyboardLoaderBase.scriptErrorMessage(uri))); + promise.reject(errorBuilder.scriptError()); } } diff --git a/common/web/keyboard-processor/src/keyboards/loaders/nodeKeyboardLoader.ts b/common/web/keyboard-processor/src/keyboards/loaders/nodeKeyboardLoader.ts index 2f622743179f9e368dfc1c73a49ac6b7e8c442dc..143e1c16c1121999b7b63fa1835cd901a853454a 100644 --- a/common/web/keyboard-processor/src/keyboards/loaders/nodeKeyboardLoader.ts +++ b/common/web/keyboard-processor/src/keyboards/loaders/nodeKeyboardLoader.ts @@ -1,4 +1,4 @@ -import { Keyboard, KeyboardHarness, KeyboardLoaderBase, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor'; +import { Keyboard, KeyboardHarness, KeyboardLoaderBase, KeyboardLoadErrorBuilder, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor'; import vm from 'vm'; import fs from 'fs'; @@ -22,7 +22,7 @@ export class NodeKeyboardLoader extends KeyboardLoaderBase { } } - protected loadKeyboardInternal(uri: string): Promise { + protected loadKeyboardInternal(uri: string, errorBuilder: KeyboardLoadErrorBuilder): Promise { // `fs` does not like 'file:///'; it IS "File System" oriented, after all, and wants a path, not a URI. if(uri.indexOf('file:///') == 0) { uri = uri.substring('file:///'.length); @@ -32,12 +32,12 @@ export class NodeKeyboardLoader extends KeyboardLoaderBase { try { script = new vm.Script(fs.readFileSync(uri).toString()); } catch (err) { - return Promise.reject(new Error(KeyboardLoaderBase.missingErrorMessage(uri))); + return Promise.reject(errorBuilder.missingError(err)); } try { script.runInContext(this.harness._jsGlobal); } catch (err) { - return Promise.reject(new Error(KeyboardLoaderBase.scriptErrorMessage(uri))); + return Promise.reject(errorBuilder.scriptError(err)); } const keyboard = this.harness.loadedKeyboard; diff --git a/common/web/keyboard-processor/tests/node/keyboard-loading.js b/common/web/keyboard-processor/tests/node/keyboard-loading.js index 1b0ccf1f70c86e9e9f84205f9fddb9003236a5db..4ae04351c0aacc88bb094bb7bd4dfc9bc4cb0447 100644 --- a/common/web/keyboard-processor/tests/node/keyboard-loading.js +++ b/common/web/keyboard-processor/tests/node/keyboard-loading.js @@ -113,8 +113,8 @@ describe('Headless keyboard loading', function() { await keyboardLoader.loadKeyboardFromPath(invalidPath); } catch (err) { missingError = err; - assert.equal(missingError.message, KeyboardLoaderBase.missingErrorMessage(invalidPath)); } + assert.isOk(missingError); let scriptLoadError; try { @@ -122,8 +122,10 @@ describe('Headless keyboard loading', function() { } catch (err) { scriptLoadError = err; } + assert.isOk(scriptLoadError); - assert.notEqual(scriptLoadError.message, KeyboardLoaderBase.scriptErrorMessage(nonKeyboardPath)); + // The main test: do the errors match? + assert.notEqual(scriptLoadError.message, missingError.message); }); }) }); \ No newline at end of file diff --git a/common/web/types/build.sh b/common/web/types/build.sh index 3c7e69b2167207c76b3d89f882305dd700f09170..ffdf3cbb83ae1053e5ef35aafabf303bed4f6b56 100755 --- a/common/web/types/build.sh +++ b/common/web/types/build.sh @@ -80,7 +80,7 @@ fi #------------------------------------------------------------------------------------------------------------------- if builder_start_action publish; then - . "$KEYMAN_ROOT/resources/build/npm-publish.inc.sh" - npm_publish + . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" + builder_publish_to_npm builder_finish_action success publish fi diff --git a/common/windows/cpp/include/.gitignore b/common/windows/cpp/include/.gitignore deleted file mode 100644 index 69ffc835cd58b37bb2f58058d770d2cf77c5ca15..0000000000000000000000000000000000000000 --- a/common/windows/cpp/include/.gitignore +++ /dev/null @@ -1 +0,0 @@ -keymanversion_build.h diff --git a/common/windows/cpp/include/keymanversion.h b/common/windows/cpp/include/keymanversion.h index a35421a2de09f5b7a3b2482dcc21b8f1524ee42b..e9d39defba2bbecd564c89f38ee0b980eb87f67c 100644 --- a/common/windows/cpp/include/keymanversion.h +++ b/common/windows/cpp/include/keymanversion.h @@ -1,7 +1,7 @@ #ifndef _KEYMANVERSION_H #define _KEYMANVERSION_H -#include "keymanversion_build.h" +#include "../../../include/keymanversion_build.h" // We should not need to add to these hard-coded version numbers for future versions, unless // we have a back-compat need to refer to a specific version. diff --git a/common/windows/cpp/include/legacy_kmx_file.h b/common/windows/cpp/include/legacy_kmx_file.h index eddbf233411cc068555dfa469651f1efbf619754..ae18543312f2303575ac276e1521c7bff9c20eb7 100644 --- a/common/windows/cpp/include/legacy_kmx_file.h +++ b/common/windows/cpp/include/legacy_kmx_file.h @@ -346,6 +346,7 @@ static_assert(sizeof(COMP_STORE) == KEYBOARDFILESTORE_SIZE, "COMP_STORE must be struct COMP_KEY { WORD Key; + WORD _reserved; DWORD Line; DWORD ShiftFlags; DWORD dpOutput; @@ -404,9 +405,18 @@ typedef COMP_STORE *PCOMP_STORE; typedef COMP_KEY *PCOMP_KEY; typedef COMP_GROUP *PCOMP_GROUP; + +typedef struct _COMPILER_OPTIONS { + DWORD dwSize; + BOOL ShouldAddCompilerVersion; + BOOL UseKmcmpLib; +} COMPILER_OPTIONS; + +typedef COMPILER_OPTIONS *PCOMPILER_OPTIONS; + typedef int (CALLBACK *CompilerMessageProc)(int line, DWORD dwMsgCode, LPSTR szText); -extern "C" BOOL __declspec(dllexport) CompileKeyboardFile(PSTR pszInfile, PSTR pszOutfile, BOOL FSaveDebug, BOOL ACompilerWarningsAsErrors, BOOL AWarnDeprecatedCode, CompilerMessageProc pMsgProc); // I4865 // I4866 +//extern "C" BOOL __declspec(dllexport) CompileKeyboardFile(PSTR pszInfile, PSTR pszOutfile, BOOL FSaveDebug, BOOL ACompilerWarningsAsErrors, BOOL AWarnDeprecatedCode, CompilerMessageProc pMsgProc); // I4865 // I4866 #endif // _COMPILER_H diff --git a/common/windows/cpp/include/vkeys.h b/common/windows/cpp/include/vkeys.h index 47a1daf3011df1e9d23adf6b1cc894d63494f6f0..6aa71cc497c0ce9eb0aaedf00737f632864509ed 100644 --- a/common/windows/cpp/include/vkeys.h +++ b/common/windows/cpp/include/vkeys.h @@ -1,4 +1,12 @@ #pragma once -extern PCWSTR VKeyNames[256]; -extern PCWSTR VKeyISO9995Names[256]; +#ifdef USE_CHAR16_T +#include +#define VKEY_CHAR KMX_UCHAR +#else +#define VKEY_CHAR WCHAR +#define lpuch(x) L ## x +#endif + +extern const VKEY_CHAR* VKeyNames[256]; +extern const VKEY_CHAR* VKeyISO9995Names[256]; diff --git a/common/windows/cpp/src/vkeys.cpp b/common/windows/cpp/src/vkeys.cpp index 4b4710baa9f54db208a6680776bb406496141d15..5bf249b3dd7cf7e8c8ac83e8c20e55a0221246fc 100644 --- a/common/windows/cpp/src/vkeys.cpp +++ b/common/windows/cpp/src/vkeys.cpp @@ -17,10 +17,9 @@ */ #include "pch.h" +#include "../include/vkeys.h" -#define lpuch(x) L ## x - -PCWSTR VKeyNames[256] = { +const VKEY_CHAR* VKeyNames[256] = { // Key Codes lpuch("K_?00"), // &H0 lpuch("K_LBUTTON"), // &H1 @@ -292,7 +291,7 @@ PCWSTR VKeyNames[256] = { lpuch("K_?FF") // &HFF }; -PCWSTR VKeyISO9995Names[256] = { +const VKEY_CHAR* VKeyISO9995Names[256] = { // Key Codes lpuch(""), // lpuch("K_?00"), // &H0 lpuch(""), // lpuch("K_LBUTTON"), // &H1 diff --git a/common/windows/delphi/Makefile b/common/windows/delphi/Makefile index 6241b54379e710ee7338916e99622495a52b8f58..2a8258f07bb3a8fe900c5a7def02a10b29245757 100644 --- a/common/windows/delphi/Makefile +++ b/common/windows/delphi/Makefile @@ -1,10 +1,9 @@ !include Defines.mak global-versions: -# Build our root version.txt +# Build our root version.txt; TODO: replace with build.sh deps cd $(KEYMAN_ROOT)\common\windows - - $(MKVER_U) $(KEYMAN_ROOT)\common\windows\cpp\include\keymanversion_build.in $(KEYMAN_ROOT)\common\windows\cpp\include\keymanversion_build.h $(MKVER_U) $(KEYMAN_ROOT)\common\windows\delphi\general\keymanversion_build.in $(KEYMAN_ROOT)\common\windows\delphi\general\keymanversion_build.inc + $(GIT_BASH_FOR_KEYMAN) $(KEYMAN_ROOT)/common/include/build.sh clean configure build !include Target.mak \ No newline at end of file diff --git a/common/windows/delphi/components/common_components.identcache b/common/windows/delphi/components/common_components.identcache deleted file mode 100644 index e216a30819a0f9d8ffa0e9eec5cc52bdbb1d0041..0000000000000000000000000000000000000000 Binary files a/common/windows/delphi/components/common_components.identcache and /dev/null differ diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index fcb51ec7d0a92ef5c3302f0297a15485ee6e7498..57f865f9b29ab9ff6165f5037d951f9afb6caedb 100644 --- a/common/windows/delphi/general/RegistryKeys.pas +++ b/common/windows/delphi/general/RegistryKeys.pas @@ -393,6 +393,8 @@ const SRegValue_IDEOptAutoSaveBeforeCompiling = 'auto save before compiling'; // CU SRegValue_IDEOptOSKAutoSaveBeforeImporting = 'osk auto save before importing'; // CU + SRegValue_IDEOptUseLegacyCompiler = 'use legacy compiler'; // CU + // Note: keeping 'web host port' reg value name to ensure settings maintained // from version 14.0 and earlier of Keyman Developer. Other values are // new with Keyman Developer 15.0 diff --git a/core/.gitignore b/core/.gitignore index e71a856da391c0a9fe861bc905e6d2aa7704f614..b02aacc47369170f728d0bb46c2068c69d2d4314 100644 --- a/core/.gitignore +++ b/core/.gitignore @@ -1,6 +1,7 @@ .vs/ build/ configure/ +resources/ # cross-compile for meson wasm, built from wasm.build..in wasm.build @@ -10,8 +11,6 @@ TIER.md VERSION.md shellHelperFunctions.sh -src/rust/keyman_keyboard_processor/target/ - # The following files/subdirs are generated by autotools when building ibus-keyman. # They can be removed after we convert ibus-keyman to use meson. .deps/ diff --git a/core/build.sh b/core/build.sh index c1ad0c3302fa993b4540d7796550cebcf6db3f94..9779419202915c6031fe0ff0c1a039eac58344d3 100755 --- a/core/build.sh +++ b/core/build.sh @@ -115,6 +115,14 @@ builder_describe_outputs \ build:arch /core/build/arch/$BUILDER_CONFIGURATION/src/libkmnkbp0.a \ build:wasm /core/build/wasm/$BUILDER_CONFIGURATION/src/libkmnkbp0.a +# Import our standard compiler defines; this is copied from +# /resources/build/meson/standard.meson.build by build.sh, because meson doesn't +# allow us to reference a file outside its root +if builder_has_action configure; then + mkdir -p "$THIS_SCRIPT_PATH/resources" + cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" +fi + # Iterate through all possible targets; note that targets that cannot be built # on the current platform have already been excluded through the archtargets # settings above diff --git a/core/meson.build b/core/meson.build index 47b8860389e3c670a1053ac5aa2da96533dbf824..81d994124c466e7d7a1f932fae32b1ef62b30f4e 100644 --- a/core/meson.build +++ b/core/meson.build @@ -14,27 +14,19 @@ project('keyboardprocessor', 'cpp', 'c', 'warning_level=2'], meson_version: '>=0.53.0') -compiler = meson.get_compiler('cpp') +# Import our standard compiler defines; this is copied from +# /resources/build/standard.meson.build by build.sh, because +# meson doesn't allow us to reference a file outside its root +subdir('resources') lib_version = '0.0.0' py = import('python') python = py.find_installation() -# Once we can assume meson 0.60 we can delete this -# (https://mesonbuild.com/Release-notes-for-0-60-0.html#msvc-compiler-now-assumes-utf8-source-code-by-default) -if compiler.get_id() == 'msvc' - add_global_arguments('/source-charset:utf-8', language: ['c', 'cpp']) -endif - -message('host_machine.system(): ' + host_machine.system()) -message('compiler.get_id(): ' + compiler.get_id()) - -cc = meson.get_compiler('c') - # TODO: Shared includes may use namespaces, etc which need future tidyup. # For now, we use KMN_KBP to inject the km::kbp::kmx namespace -defns = ['-DKMN_KBP'] +defns += ['-DKMN_KBP'] # #define DEBUG when we are on a debug build if get_option('buildtype') == 'debug' diff --git a/core/src/meson.build b/core/src/meson.build index 4694a0b8d72c2650fb92f2cf3d0935b92c21aee0..97b929164647288845817f40f6824a8aa1b17caf 100644 --- a/core/src/meson.build +++ b/core/src/meson.build @@ -4,58 +4,21 @@ # Authors: Tim Eves (TSE) # -defns += ['-DKMN_KBP_EXPORTING'] version_res = [] -if compiler.get_id() == 'gcc' or compiler.get_id() == 'clang' - warns = [ - '-Wctor-dtor-privacy', - '-Wdouble-promotion', - '-Wendif-labels', - '-Wno-unknown-pragmas', - '-Wno-missing-field-initializers', - '-Wnon-virtual-dtor', - '-Wshadow' - ] - flags = [ - '-fvisibility=hidden', - '-fvisibility-inlines-hidden' - ] - links = [] - - if compiler.get_id() == 'clang' - warns += [ - '-Wimplicit-fallthrough', - '-Wno-double-promotion', - '-Wshorten-64-to-32' - ] - endif - - if host_machine.system() == 'darwin' - warns += ['-Wno-ctor-dtor-privacy', '-Wno-non-virtual-dtor'] - endif -endif - -if compiler.get_id() == 'msvc' - warns = [] - flags = [] - defns += [ - '-D_SCL_SECURE_NO_WARNINGS', - '-D_CRT_SECURE_NO_WARNINGS', - '-DUNICODE' - ] - links = [] +# TODO: shouldn't this be defined only for dylib and not static lib? +defns += ['-DKMN_KBP_EXPORTING'] +if cpp_compiler.get_id() == 'msvc' + defns += ['-DUNICODE'] # /n = append null # /c65001 = utf-8 file format version_res += import('windows').compile_resources('version.rc', args:['/n','/c65001']) endif -if compiler.get_id() == 'emscripten' - warns = [] - flags = [] - defns = ['-DKMN_KBP'] - links = [] +if cpp_compiler.get_id() == 'emscripten' + # TODO: why do we need this defn here? + defns += ['-DKMN_KBP'] endif kmx_files = files( diff --git a/core/tests/kmx_test_source/meson.build b/core/tests/kmx_test_source/meson.build index 4cfdd5661d1dd1d9ffbf7fe1a7139d4cc917cd3d..691839047f82f7995ec23b79682eb698ff9e0e92 100644 --- a/core/tests/kmx_test_source/meson.build +++ b/core/tests/kmx_test_source/meson.build @@ -1,4 +1,6 @@ -if compiler.get_id() == 'gcc' or compiler.get_id() == 'clang' or compiler.get_id() == 'emscripten' + +# TODO -- why are these differing from the standard.meson.build flags? +if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' or cpp_compiler.get_id() == 'emscripten' warns = [ '-Wno-missing-field-initializers', '-Wno-unused-parameter' diff --git a/core/tests/meson.build b/core/tests/meson.build index 1d37806947fd80f3e3b9b0fbff5a4cdacb2534a6..e2e29975822dcf9918f41d98ca64ca629289f625 100644 --- a/core/tests/meson.build +++ b/core/tests/meson.build @@ -22,7 +22,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) - python_ctypes_compatible = r.stdout().to_int() == compiler.sizeof('void *') + 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.') endif diff --git a/core/tests/unit/emscripten_filesystem.cpp b/core/tests/unit/emscripten_filesystem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c5e180f6beabf67d14f0d526f76b83718a4d564a --- /dev/null +++ b/core/tests/unit/emscripten_filesystem.cpp @@ -0,0 +1,72 @@ + + +#ifdef __EMSCRIPTEN__ + +#include +#include +#include + +const std::string get_wasm_file_path(const std::string& filename) { + // Verify that we are passing a fully-qualified path + // TODO: we need to support relative paths based on CWD +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path ENTER (" << filename << ")" << std::endl; +#endif + + assert( + (filename.length() > 0 && filename.at(0) == '/') || + (filename.length() > 1 && filename.at(1) == ':') + ); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path assert passed " << std::endl; +#endif + + EM_ASM_({ + //console.log('EM_ASM enter'); + let path = Module.UTF8ToString($0); + const isWin32Path = path.match(/^[a-zA-Z]:/); + + //console.log('EM_ASM path = '+path); + let root = '/nodefs-mount'; + if(!FS.analyzePath(root).exists) { + //console.log('EM_ASM mkdir '+root); + FS.mkdir(root); + if(!isWin32Path) { + //console.log('EM_ASM mount '+root); + FS.mount(NODEFS, {root : '/'}, root); + } + } + + if(isWin32Path) { + // Win32 path, one mount per drive + root += "/" + path.charAt(0); + if(!FS.analyzePath(root).exists) { + //console.log('EM_ASM mkdir '+root); + FS.mkdir(root); + //console.log('EM_ASM mount '+root); + FS.mount(NODEFS, {root : path.substr(0,3) }, root); + } + } + }, filename.c_str()); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path EM_ASM_ passed " << std::endl; +#endif + + std::string f = std::string("/nodefs-mount"); + + if(filename.length() > 2 && filename.at(1) == ':') { + f += std::string("/") + filename.at(0) + filename.substr(2); + } else { + f += filename; + } + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path opening virtual path: " << f << std::endl; +#endif + + return f; +} + +#endif diff --git a/core/tests/unit/emscripten_filesystem.h b/core/tests/unit/emscripten_filesystem.h new file mode 100644 index 0000000000000000000000000000000000000000..c5fb8e016a077464ca17c72cbf760c293a8deee1 --- /dev/null +++ b/core/tests/unit/emscripten_filesystem.h @@ -0,0 +1,8 @@ +#pragma once + +#ifdef __EMSCRIPTEN__ +#include + +const std::string get_wasm_file_path(const std::string& filename); + +#endif \ No newline at end of file diff --git a/core/tests/unit/json/meson.build b/core/tests/unit/json/meson.build index 42106976cd27d5864751950d24c06e0fd120cb6a..6289d7db0cb1f6bba414e7ff816a80615600a2e9 100644 --- a/core/tests/unit/json/meson.build +++ b/core/tests/unit/json/meson.build @@ -4,7 +4,7 @@ # Authors: Tim Eves (TSE) # -if compiler.get_id() == 'emscripten' +if cpp_compiler.get_id() == 'emscripten' tests_flags = ['-lnodefs.js'] else tests_flags = [] diff --git a/core/tests/unit/kmnkbd/action_items.hpp b/core/tests/unit/kmnkbd/action_items.hpp index 676e904eed15482e09611a606ee36162f06bbc21..253b8c740a5aea83f74a796cee69f2380704a189 100644 --- a/core/tests/unit/kmnkbd/action_items.hpp +++ b/core/tests/unit/kmnkbd/action_items.hpp @@ -2,7 +2,7 @@ #include #include -#include "../test_assert.h" +#include namespace { diff --git a/core/tests/unit/kmnkbd/debug_api.cpp b/core/tests/unit/kmnkbd/debug_api.cpp index b8c5b4c6ecb88e72df19b5e2703e05a41ec4e8af..b4cfae6ab39494a095978f0ebf4a9c16e1a98420 100644 --- a/core/tests/unit/kmnkbd/debug_api.cpp +++ b/core/tests/unit/kmnkbd/debug_api.cpp @@ -18,7 +18,8 @@ #include "action_items.hpp" #include "debug_items.hpp" -#include "../test_assert.h" +#include +#include "../emscripten_filesystem.h" using namespace km::kbp::kmx; @@ -30,7 +31,7 @@ km_kbp_option_item test_env_opts[] = km_kbp_keyboard * test_kb = nullptr; km_kbp_state * test_state = nullptr; km_kbp_context_item * citems = nullptr; -char * arg_path; +std::string arg_path; void teardown() { if(citems) { @@ -71,7 +72,7 @@ void setup(const char *keyboard) { * Test 1: Start with debugging disabled */ void test_debugging_disabled() { - setup("000 - null keyboard.kmx"); + setup("k_000___null_keyboard.kmx"); try_status(km_kbp_state_debug_set(test_state, 0)); try_status(km_kbp_process_event(test_state, KM_KBP_VKEY_S, KM_KBP_MODIFIER_SHIFT, 1, KM_KBP_EVENT_FLAG_DEFAULT)); assert(debug_items(test_state, { @@ -88,7 +89,7 @@ void test_debugging_disabled() { * Test 2: Debugging enabled, no rule match */ void test_debugging_no_rule_match() { - setup("000 - null keyboard.kmx"); + setup("k_000___null_keyboard.kmx"); DEBUG_GROUP gp = {u"Main"}; try_status(km_kbp_state_debug_set(test_state, 1)); try_status(km_kbp_process_event(test_state, KM_KBP_VKEY_S, KM_KBP_MODIFIER_SHIFT, 1, KM_KBP_EVENT_FLAG_DEFAULT)); @@ -109,7 +110,7 @@ void test_debugging_no_rule_match() { * Test 3: Debugging enabled, function key pressed, no rule match */ void test_debugging_function_key() { - setup("000 - null keyboard.kmx"); + setup("k_000___null_keyboard.kmx"); DEBUG_GROUP gp = {u"Main"}; try_status(km_kbp_state_debug_set(test_state, 1)); try_status(km_kbp_process_event(test_state, KM_KBP_VKEY_F1, 0, 1, KM_KBP_EVENT_FLAG_DEFAULT)); @@ -131,9 +132,9 @@ void test_debugging_function_key() { * Test 4: basic rule match */ void test_basic_rule_matches() { - setup("002 - basic input Unicode.kmx"); + setup("k_002___basic_input_unicode.kmx"); DEBUG_GROUP gp = {u"Main"}; - DEBUG_KEY kp = { 'F', /*line*/16, /*shift*/0 }; // vkey is a char + DEBUG_KEY kp = { 'F', /*line*/17, /*shift*/0 }; // vkey is a char try_status(km_kbp_state_debug_set(test_state, 1)); // 'DE' + 'F' > U+0E04 U+0E05 U+0E06 @@ -197,12 +198,12 @@ void test_basic_rule_matches() { * Test 5: Multiple groups */ void test_multiple_groups() { - setup("030 - multiple groups.kmx"); + setup("k_030___multiple_groups.kmx"); DEBUG_GROUP gp = {u"Main"}, gpa = {u"a"}, gpb = {u"b"}; - DEBUG_KEY kp1 = { KM_KBP_VKEY_1, /*line*/12, /*shift*/KM_KBP_MODIFIER_VIRTUALKEY }, - kp2 = { KM_KBP_VKEY_2, /*line*/13, /*shift*/KM_KBP_MODIFIER_VIRTUALKEY }, - kpa = { 0, /*line*/19, /*shift*/0 }, - kpb = { 0, /*line*/23, /*shift*/0 }; + DEBUG_KEY kp1 = { KM_KBP_VKEY_1, /*line*/13, /*shift*/KM_KBP_MODIFIER_VIRTUALKEY }, + kp2 = { KM_KBP_VKEY_2, /*line*/14, /*shift*/KM_KBP_MODIFIER_VIRTUALKEY }, + kpa = { 0, /*line*/20, /*shift*/0 }, + kpb = { 0, /*line*/24, /*shift*/0 }; try_status(km_kbp_state_debug_set(test_state, 1)); @@ -278,10 +279,10 @@ void test_multiple_groups() { * Test 6: store offsets */ void test_store_offsets() { - setup("044 - if and context.kmx"); + setup("k_044___if_and_context.kmx"); DEBUG_GROUP gp = {u"Main"}; - DEBUG_KEY kpa = { 'a', /*line*/15, }, - kpb = { 'b', /*line*/19, }; + DEBUG_KEY kpa = { 'a', /*line*/16, }, + kpb = { 'b', /*line*/20, }; try_status(km_kbp_state_debug_set(test_state, 1)); @@ -352,9 +353,9 @@ void test_store_offsets() { * Test 7: set option */ void test_set_option() { - setup("021 - options.kmx"); + setup("k_021___options.kmx"); DEBUG_GROUP gp = {u"Main"}; - DEBUG_KEY kp1 = { '1', /*line*/16, }; + DEBUG_KEY kp1 = { '1', /*line*/17, }; DEBUG_STORE sp = {0, u"foo", u"1"}; try_status(km_kbp_state_debug_set(test_state, 1)); @@ -379,9 +380,9 @@ void test_set_option() { * Test 8: save option */ void test_save_option() { - setup("023 - options with save.kmx"); + setup("k_023___options_with_save.kmx"); DEBUG_GROUP gp = {u"Main"}; - DEBUG_KEY kp1 = { '2', /*line*/19, }; + DEBUG_KEY kp1 = { '2', /*line*/21, }; // DEBUG_STORE sp = {0, u"foo", u"0"}; km_kbp_option_item opt = {u"foo", u"0", KM_KBP_OPT_KEYBOARD}; @@ -412,7 +413,7 @@ void test_save_option() { * an 'unknown' backspace because we are at start-of-context */ void test_backspace_markers() { - setup("000 - null keyboard.kmx"); + setup("k_000___null_keyboard.kmx"); km_kbp_context_item marker_context[] = { {KM_KBP_CT_MARKER, {0,}, {1}}, {KM_KBP_CT_MARKER, {0,}, {1}}, @@ -496,7 +497,11 @@ int main(int argc, char *argv []) { } console_color::enabled = console_color::isaterminal() || arg_color; +#ifdef __EMSCRIPTEN__ + arg_path = get_wasm_file_path(argv[arg_color ? 2 : 1]); +#else arg_path = argv[arg_color ? 2 : 1]; +#endif test_debugging_disabled(); test_debugging_no_rule_match(); diff --git a/core/tests/unit/kmnkbd/debug_items.hpp b/core/tests/unit/kmnkbd/debug_items.hpp index 137325d7315b2e228ac690c5e90bad64f45eb115..95703005c45e573a8e57bd955dbac2396de5bf48 100644 --- a/core/tests/unit/kmnkbd/debug_items.hpp +++ b/core/tests/unit/kmnkbd/debug_items.hpp @@ -4,7 +4,7 @@ #include "kmx/kmx_base.h" #include "kmx/kmx_xstring.h" -#include "../test_assert.h" +#include using namespace km::kbp::kmx; diff --git a/core/tests/unit/kmnkbd/meson.build b/core/tests/unit/kmnkbd/meson.build index 16884298e574ec81307019594aa5c39b9c09fad9..049770fa2f7bebf3786cc24b042abcb0c8fcf8bf 100644 --- a/core/tests/unit/kmnkbd/meson.build +++ b/core/tests/unit/kmnkbd/meson.build @@ -4,7 +4,8 @@ # Authors: Tim Eves (TSE) # -if compiler.get_id() == 'gcc' or compiler.get_id() == 'clang' or compiler.get_id() == 'emscripten' +# TODO -- why are these differing from the standard.meson.build flags? +if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' or cpp_compiler.get_id() == 'emscripten' warns = [ '-Wno-missing-field-initializers', '-Wno-unused-parameter' @@ -13,7 +14,7 @@ else warns = [] endif -defns+=['-DKMN_KBP_STATIC'] +local_defns = ['-DKMN_KBP_STATIC'] tests = [ ['context-api', 'context_api.cpp'], ['keyboard-api', 'keyboard_api.cpp'], @@ -24,19 +25,16 @@ tests = [ ['kmx_context', 'test_kmx_context.cpp'], ] -if compiler.get_id() == 'emscripten' - tests_flags = ['--embed-file', join_paths(meson.current_source_dir(),'..','kmx','@/')] - source_path = '/' - test_path = '/' -else - tests_flags = [] - source_path = meson.current_source_dir() - test_path = join_paths(meson.current_source_dir(), '..', 'kmx') +test_path = join_paths(meson.current_build_dir(), '..', 'kmx') +tests_flags = [] + +if cpp_compiler.get_id() == 'emscripten' + tests_flags += ['-lnodefs.js', '-sEXPORTED_RUNTIME_METHODS=[\'UTF8ToString\']'] endif foreach t : tests - bin = executable(t[0], t[1], - cpp_args: defns + warns, + bin = executable(t[0], [t[1], '../emscripten_filesystem.cpp'], + cpp_args: local_defns + defns + warns, include_directories: [inc, libsrc], link_args: links + tests_flags, objects: lib.extract_all_objects(recursive: false)) diff --git a/core/tests/unit/kmnkbd/state_api.cpp b/core/tests/unit/kmnkbd/state_api.cpp index 37964489b78fb05dc62076e1857f8465fa94a859..3ae446541c0f2a97d9ab6e6dd77ade78fc92cd18 100644 --- a/core/tests/unit/kmnkbd/state_api.cpp +++ b/core/tests/unit/kmnkbd/state_api.cpp @@ -15,7 +15,7 @@ #include "state.hpp" #include "action_items.hpp" -#include "../test_assert.h" +#include #if defined(__GNUC__) || defined(__clang__) #define PRAGMA(X) _Pragma(#X) diff --git a/core/tests/unit/kmnkbd/test_kmx_context.cpp b/core/tests/unit/kmnkbd/test_kmx_context.cpp index a05dfed543b070aec5c0ca939659775bf7120210..1023d1611e3244eee02b25f48667b9d7f73f30cb 100644 --- a/core/tests/unit/kmnkbd/test_kmx_context.cpp +++ b/core/tests/unit/kmnkbd/test_kmx_context.cpp @@ -13,7 +13,7 @@ #include "../../../src/kmx/kmx_context.h" #include "../../../src/kmx/kmx_processevent.h" // for Debug_UnicodeString #include "../../../src/kmx/kmx_xstring.h" -#include "../test_assert.h" +#include using namespace km::kbp::kmx; using namespace std; diff --git a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp index c4b94c52b21e4cca4258ebcbab5885d3cc23e30c..d578fa7e3813aa0e86e64a8855a360d5c78a5988 100644 --- a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp +++ b/core/tests/unit/kmnkbd/test_kmx_xstring.cpp @@ -19,7 +19,7 @@ #include #include "../../../src/kmx/kmx_xstring.h" #include -#include "../test_assert.h" +#include using namespace km::kbp::kmx; using namespace std; diff --git a/core/tests/unit/kmx/000 - null keyboard.kmx b/core/tests/unit/kmx/000 - null keyboard.kmx deleted file mode 100644 index f0e9da6bcc360f9316a509cccb5cc1efad7d2718..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/000 - null keyboard.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/001 - basic input UnicodeI.kmx b/core/tests/unit/kmx/001 - basic input UnicodeI.kmx deleted file mode 100644 index fc59fa6a2d6ac3b030a34a8f49d555e87921c20e..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/001 - basic input UnicodeI.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/002 - basic input Unicode.kmx b/core/tests/unit/kmx/002 - basic input Unicode.kmx deleted file mode 100644 index 0d2539a641a2f064f9670526ef56c6903486ace3..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/002 - basic input Unicode.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/003 - nul.kmx b/core/tests/unit/kmx/003 - nul.kmx deleted file mode 100644 index 79046c521a884a372174b08c1cef5814648fcd9b..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/003 - nul.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/004 - basic input (shift 2).kmx b/core/tests/unit/kmx/004 - basic input (shift 2).kmx deleted file mode 100644 index a31840fa2432fb62870858a2cb01dd1582792eff..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/004 - basic input (shift 2).kmx and /dev/null differ diff --git a/core/tests/unit/kmx/005 - nul with initial context.kmx b/core/tests/unit/kmx/005 - nul with initial context.kmx deleted file mode 100644 index 79046c521a884a372174b08c1cef5814648fcd9b..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/005 - nul with initial context.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/006 - vkey input (shift ctrl).kmx b/core/tests/unit/kmx/006 - vkey input (shift ctrl).kmx deleted file mode 100644 index 5320c4405c43259e98b48c703396d92a8b0e09d5..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/006 - vkey input (shift ctrl).kmx and /dev/null differ diff --git a/core/tests/unit/kmx/007 - vkey input (ctrl alt).kmx b/core/tests/unit/kmx/007 - vkey input (ctrl alt).kmx deleted file mode 100644 index a76e77d6d4f3826d54902938a897a709427896a0..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/007 - vkey input (ctrl alt).kmx and /dev/null differ diff --git a/core/tests/unit/kmx/008 - vkey input (ctrl alt 2).kmx b/core/tests/unit/kmx/008 - vkey input (ctrl alt 2).kmx deleted file mode 100644 index c197fa727a4accf5354be51c45ab050b7f967a45..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/008 - vkey input (ctrl alt 2).kmx and /dev/null differ diff --git a/core/tests/unit/kmx/012 - ralt.kmx b/core/tests/unit/kmx/012 - ralt.kmx deleted file mode 100644 index cbab878a8a91bcbc1fc0bfdfbd5217843ce73df6..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/012 - ralt.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/013 - deadkeys.kmx b/core/tests/unit/kmx/013 - deadkeys.kmx deleted file mode 100644 index 68d8f4a313dd749435ea44f965d33f73d5e2f867..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/013 - deadkeys.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/014 - groups and virtual keys.kmx b/core/tests/unit/kmx/014 - groups and virtual keys.kmx deleted file mode 100644 index 5a24d0909e5de0e01a61f54b55e6a4b2b6aa8f5d..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/014 - groups and virtual keys.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/015 - ralt 2.kmx b/core/tests/unit/kmx/015 - ralt 2.kmx deleted file mode 100644 index f565b4fee44512c9a04ca4241c6e9cc0625f2576..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/015 - ralt 2.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/017 - space mnemonic kbd.kmx b/core/tests/unit/kmx/017 - space mnemonic kbd.kmx deleted file mode 100644 index 797014bda1e64c5e00a8458fb0450cb3a7fda348..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/017 - space mnemonic kbd.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/018 - nul testing.kmx b/core/tests/unit/kmx/018 - nul testing.kmx deleted file mode 100644 index 13204ad251e30822fec75021ef01248bd8b14688..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/018 - nul testing.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/019 - multiple deadkeys.kmx b/core/tests/unit/kmx/019 - multiple deadkeys.kmx deleted file mode 100644 index 44113e2d350ffba99dc565b5a32717b810f9d0c2..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/019 - multiple deadkeys.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/020 - deadkeys and backspace.kmx b/core/tests/unit/kmx/020 - deadkeys and backspace.kmx deleted file mode 100644 index 3c245041b06b12ae74bc6dc6be8af2275805597e..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/020 - deadkeys and backspace.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/021 - options.kmx b/core/tests/unit/kmx/021 - options.kmx deleted file mode 100644 index c5550c1018678e1bbc9710042d906831e8a75f34..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/021 - options.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/022 - options with preset.kmx b/core/tests/unit/kmx/022 - options with preset.kmx deleted file mode 100644 index 57f3720de7a20f83ab4cdf0f40c0c7bc0dd563c7..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/022 - options with preset.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/023 - options with save.kmx b/core/tests/unit/kmx/023 - options with save.kmx deleted file mode 100644 index f6689ce47ee12a3dc9a4f9253ba049a7f568d15d..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/023 - options with save.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/024 - options with save and preset.kmx b/core/tests/unit/kmx/024 - options with save and preset.kmx deleted file mode 100644 index 029a136f7881af7758744280096d116ed0c57dd6..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/024 - options with save and preset.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/025 - options with reset.kmx b/core/tests/unit/kmx/025 - options with reset.kmx deleted file mode 100644 index e1595c84667399496c72de3a8f6afc2baf926f77..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/025 - options with reset.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/026 - system stores.kmx b/core/tests/unit/kmx/026 - system stores.kmx deleted file mode 100644 index da2e0b30c091ee33aff3a38498015793bd8d10cf..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/026 - system stores.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/027 - system stores 2.kmx b/core/tests/unit/kmx/027 - system stores 2.kmx deleted file mode 100644 index 43d58aaa2bcd557f66e55ab294e582e5dde9c0ba..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/027 - system stores 2.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/028 - smp.kmx b/core/tests/unit/kmx/028 - smp.kmx deleted file mode 100644 index da89544b3e99343683c943c08c0dc690632990be..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/028 - smp.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/029 - beep.kmx b/core/tests/unit/kmx/029 - beep.kmx deleted file mode 100644 index 1e809bdb338e230c2397218ec049c5f8ca4254d1..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/029 - beep.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/030 - multiple groups.kmx b/core/tests/unit/kmx/030 - multiple groups.kmx deleted file mode 100644 index 9b75bfca40c4ba3ec248c47f42e4ecc0f2e982a2..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/030 - multiple groups.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/031 - caps lock.kmx b/core/tests/unit/kmx/031 - caps lock.kmx deleted file mode 100644 index e317f13349c7e2582fea5f7b1cd91b59e30820a3..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/031 - caps lock.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/032 - caps control.kmx b/core/tests/unit/kmx/032 - caps control.kmx deleted file mode 100644 index 67d7ac2102871d8273f32634bb3929be43f3562e..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/032 - caps control.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/033 - caps always off.kmx b/core/tests/unit/kmx/033 - caps always off.kmx deleted file mode 100644 index 08bd6521fe6c458c83b95fb857eff1a91ff6eba6..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/033 - caps always off.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/034 - options double set reset.kmx b/core/tests/unit/kmx/034 - options double set reset.kmx deleted file mode 100644 index 92ef0da0ad6ebd1a189e6447dad159ee0e0e8341..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/034 - options double set reset.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/035 - options double set staged.kmx b/core/tests/unit/kmx/035 - options double set staged.kmx deleted file mode 100644 index 61970709ea2fa70ccd38d8ec89a5cd1cd8cfd90b..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/035 - options double set staged.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/036 - options - double reset staged.kmx b/core/tests/unit/kmx/036 - options - double reset staged.kmx deleted file mode 100644 index 2cc4b21993b47a726ce8dd160c1cefc403e4b336..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/036 - options - double reset staged.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/037 - options - double reset.kmx b/core/tests/unit/kmx/037 - options - double reset.kmx deleted file mode 100644 index 2e8120f6e501b4f97829be0c99eacb2cafa5cb51..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/037 - options - double reset.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/038 - punctkeys.kmx b/core/tests/unit/kmx/038 - punctkeys.kmx deleted file mode 100644 index 2b892d51b8a326d45a3c6592df2b08a9de5ee489..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/038 - punctkeys.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/039 - generic ctrlalt.kmx b/core/tests/unit/kmx/039 - generic ctrlalt.kmx deleted file mode 100644 index 897c02624daf5dbdb092a801d23c61267060a617..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/039 - generic ctrlalt.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/040 - long context.kmx b/core/tests/unit/kmx/040 - long context.kmx deleted file mode 100644 index c6025add0a57e2deb6a66f062c75836a74de1dac..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/040 - long context.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/041 - long context and deadkeys.kmx b/core/tests/unit/kmx/041 - long context and deadkeys.kmx deleted file mode 100644 index d92dbb46ee67632f241d64f62efea1ef663d961e..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/041 - long context and deadkeys.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/042 - long context and split deadkeys.kmx b/core/tests/unit/kmx/042 - long context and split deadkeys.kmx deleted file mode 100644 index 49b539ffb104000a192767736f40a4bfc8d123d1..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/042 - long context and split deadkeys.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/043 - output and keystroke.kmx b/core/tests/unit/kmx/043 - output and keystroke.kmx deleted file mode 100644 index 120b42e2bc5539e3b825d750deba5a6ab9c5e345..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/043 - output and keystroke.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/044 - if and context.kmx b/core/tests/unit/kmx/044 - if and context.kmx deleted file mode 100644 index ae70c6ab81338650ff8173175ab3a36b0c78ed37..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/044 - if and context.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/045 - deadkey and context.kmx b/core/tests/unit/kmx/045 - deadkey and context.kmx deleted file mode 100644 index 2ae9ff2eb60e6cff911968f99f5b84bac19ad41f..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/045 - deadkey and context.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/046 - deadkey and contextex.kmx b/core/tests/unit/kmx/046 - deadkey and contextex.kmx deleted file mode 100644 index 8a1a97b556a1404c36b29fab22b1119efc920633..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/046 - deadkey and contextex.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/047 - caps always off initially on.kmx b/core/tests/unit/kmx/047 - caps always off initially on.kmx deleted file mode 100644 index a890017c4cd0de5589a95a9b974bee5972773a4d..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/047 - caps always off initially on.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/048 - modifier keys keep context.kmx b/core/tests/unit/kmx/048 - modifier keys keep context.kmx deleted file mode 100644 index 52c70f61e048f18e841e18d1137ba6a7c988e63b..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/048 - modifier keys keep context.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/README.md b/core/tests/unit/kmx/README.md index a1ced307f9b68198ec1df22c5f03900af6b7d3ce..909d891f7da9dbe7b894c1592cdaf46572afa173 100644 --- a/core/tests/unit/kmx/README.md +++ b/core/tests/unit/kmx/README.md @@ -65,12 +65,12 @@ Alternatively it's possible to run a single test with: ```bash cd core -build/arch/debug/tests/unit/kmx/kmx 'tests/unit/kmx/038 - punctkeys.kmn' 'tests/unit/kmx/038 - punctkeys.kmx' +build/arch/debug/tests/unit/kmx/kmx '../common/test/keyboards/baseline/k_038___punctkeys.kmn' '../common/test/keyboards/baseline/k_038___punctkeys.kmx' ``` or shorter: ```bash cd core -build/arch/debug/tests/unit/kmx/kmx 'tests/unit/kmx/038 - punctkeys'.km{n,x} +build/arch/debug/tests/unit/kmx/kmx '../common/test/keyboards/baseline/k_038___punctkeys'.km{n,x} ``` diff --git a/core/tests/unit/kmx/fixtures/binary/meson.build b/core/tests/unit/kmx/fixtures/binary/meson.build index 5998a3b1e96de454acda8006b5fe7d7b3d532dbf..fb01836edeb241fba410be0e60d57e4f7d04a94a 100644 --- a/core/tests/unit/kmx/fixtures/binary/meson.build +++ b/core/tests/unit/kmx/fixtures/binary/meson.build @@ -9,11 +9,7 @@ # Build all binary test keyboards -if compiler.get_id() == 'emscripten' - binary_test_path = '/' -else - binary_test_path = meson.current_build_dir() -endif +binary_test_path = meson.current_build_dir() binary_tests = [ 'b_000_zero_checksum' diff --git a/core/tests/unit/kmx/kmx.cpp b/core/tests/unit/kmx/kmx.cpp index 8f91844fbb7c1e4f821f36caabb9baea5e791560..a0c8eaa1b2cba2c5e61732df15c4128ec5419247 100644 --- a/core/tests/unit/kmx/kmx.cpp +++ b/core/tests/unit/kmx/kmx.cpp @@ -24,8 +24,9 @@ #include "state.hpp" #include "utfcodec.hpp" -#include "../test_assert.h" -#include "../test_color.h" +#include +#include +#include "../emscripten_filesystem.h" #include "kmx_test_source.hpp" @@ -334,5 +335,10 @@ int main(int argc, char *argv[]) { console_color::enabled = console_color::isaterminal() || arg_color; km::kbp::kmx::g_debug_ToConsole = TRUE; + +#ifdef __EMSCRIPTEN__ + return run_test(get_wasm_file_path(argv[first_arg]), get_wasm_file_path(argv[first_arg + 1])); +#else return run_test(argv[first_arg], argv[first_arg + 1]); +#endif } diff --git a/core/tests/unit/kmx/kmx_imsample.kmx b/core/tests/unit/kmx/kmx_imsample.kmx deleted file mode 100644 index 754c0985ae2bf73e99d134f34a1254319968f309..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/kmx_imsample.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/kmx_imx.cpp b/core/tests/unit/kmx/kmx_imx.cpp index 2afb9c63bc037631db4fc7c3201f5f98f0097077..b93525724633f32da92a33abd61e49962af3c760 100644 --- a/core/tests/unit/kmx/kmx_imx.cpp +++ b/core/tests/unit/kmx/kmx_imx.cpp @@ -11,12 +11,13 @@ #include "path.hpp" #include "state.hpp" #include "../kmnkbd/action_items.hpp" -#include "../test_assert.h" -#include "../test_color.h" +#include +#include +#include "../emscripten_filesystem.h" #include -#include -#include +#include +#include /** This test will test the infrastructure around IMX third party librays * and callback. The functions tested are: @@ -31,10 +32,10 @@ km_kbp_option_item test_env_opts[] = KM_KBP_OPTIONS_END }; -std::map expected_imx_map { {4, "imsample.dll:DF"}, - {5, "imsample.dll:func2"}, - {6, "another.dll:func3"}, - {7, "another.dll:func4"}, +std::map expected_imx_map { {3, "imsample.dll:DF"}, + {4, "imsample.dll:func2"}, + {5, "another.dll:func3"}, + {6, "another.dll:func4"}, }; std::map g_extract_imx_map; @@ -97,7 +98,9 @@ uint8_t test_imx_callback(km_kbp_state *state, uint32_t imx_id, void *callback_o std::cout << "test_imx_callback function name: " << it->second << std::endl; km_kbp_action_item *a_items = new km_kbp_action_item[10]; switch (imx_id) { - case 4: + // this corresponds to store index; if these change, the values + // here will need updating + case 3: a_items[0].type = KM_KBP_IT_CHAR; a_items[0].character = km_kbp_usv('X'); @@ -105,7 +108,7 @@ uint8_t test_imx_callback(km_kbp_state *state, uint32_t imx_id, void *callback_o a_items[2].type = KM_KBP_IT_END; km_kbp_state_queue_action_items(state, a_items); break; - case 5: + case 4: a_items[0].type = KM_KBP_IT_CHAR; a_items[0].character = km_kbp_usv('Y'); @@ -116,7 +119,7 @@ uint8_t test_imx_callback(km_kbp_state *state, uint32_t imx_id, void *callback_o a_items[3].type = KM_KBP_IT_END; km_kbp_state_queue_action_items(state, a_items); break; - case 6: + case 5: a_items[0].type = KM_KBP_IT_BACK; a_items[0].backspace.expected_type = KM_KBP_BT_CHAR; a_items[0].backspace.expected_value = km_kbp_usv('A'); @@ -125,7 +128,7 @@ uint8_t test_imx_callback(km_kbp_state *state, uint32_t imx_id, void *callback_o a_items[2].type = KM_KBP_IT_END; km_kbp_state_queue_action_items(state, a_items); break; - case 7: { + case 6: { a_items[0].type = KM_KBP_IT_INVALIDATE_CONTEXT; a_items[1].type = KM_KBP_IT_END; km_kbp_state_queue_action_items(state, a_items); @@ -260,7 +263,14 @@ int main(int argc, char *argv []) { } console_color::enabled = console_color::isaterminal() || arg_color; km::kbp::kmx::g_debug_ToConsole = TRUE; + +#ifdef __EMSCRIPTEN__ + test_imx_list(get_wasm_file_path(argv[first_arg])); + test_queue_actions(get_wasm_file_path(argv[first_arg])); +#else test_imx_list(argv[first_arg]); test_queue_actions(argv[first_arg]); +#endif + return 0; } diff --git a/core/tests/unit/kmx/kmx_key_list.cpp b/core/tests/unit/kmx/kmx_key_list.cpp index 0bd2bce2483c0971f57537030422aeff8de760b8..d4750c44d3a9a1a6448d3715647640a16b68a685 100644 --- a/core/tests/unit/kmx/kmx_key_list.cpp +++ b/core/tests/unit/kmx/kmx_key_list.cpp @@ -12,8 +12,9 @@ #include "state.hpp" #include -#include "../test_assert.h" -#include "../test_color.h" +#include +#include +#include "../emscripten_filesystem.h" using namespace km::kbp::kmx; @@ -107,7 +108,11 @@ int main(int argc, char *argv []) { } console_color::enabled = console_color::isaterminal() || arg_color; +#ifdef __EMSCRIPTEN__ + test_key_list(get_wasm_file_path(argv[first_arg])); +#else test_key_list(argv[first_arg]); +#endif return 0; } diff --git a/core/tests/unit/kmx/kmx_key_list.kmx b/core/tests/unit/kmx/kmx_key_list.kmx deleted file mode 100644 index efb6540fcec6057653b03180095b2da757b0c222..0000000000000000000000000000000000000000 Binary files a/core/tests/unit/kmx/kmx_key_list.kmx and /dev/null differ diff --git a/core/tests/unit/kmx/meson.build b/core/tests/unit/kmx/meson.build index 048b8880112b59989b7bd9ba2e4e04078d87bbfc..7e4b9f8a77c349935debb0dd4febb62eac1e0d0f 100644 --- a/core/tests/unit/kmx/meson.build +++ b/core/tests/unit/kmx/meson.build @@ -5,7 +5,8 @@ # History: 19 Oct 2018 - TSE - Added test for context API functions. # -if compiler.get_id() == 'gcc' or compiler.get_id() == 'clang' or compiler.get_id() == 'emscripten' +# TODO -- why are these differing from the standard.meson.build flags? +if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' or cpp_compiler.get_id() == 'emscripten' warns = [ '-Wno-missing-field-initializers', '-Wno-unused-parameter' @@ -14,116 +15,94 @@ else warns = [] endif +source_path = meson.current_source_dir() +test_path = meson.current_build_dir() +tests_flags = [] +common_test_keyboards_baseline = source_path / '../../../../common/test/keyboards/baseline' -if compiler.get_id() == 'emscripten' - tests_flags = ['--embed-file', join_paths(meson.current_source_dir(),'@/')] - # we have to link in files from the binary folder also as the binary tests - # use the kmx test runner. - tests_flags += ['--embed-file', join_paths(meson.current_build_dir(),'fixtures','binary','@')] - source_path = '/' - test_path = '/' -else - tests_flags = [] - source_path = meson.current_source_dir() - test_path = meson.current_build_dir() +if cpp_compiler.get_id() == 'emscripten' + # TODO: we will move the tests to ES6 in the future + # '-sMODULARIZE', '-sEXPORT_ES6', + tests_flags += ['-lnodefs.js', '-sEXPORTED_RUNTIME_METHODS=[\'UTF8ToString\']'] endif kmx = executable('kmx', - 'kmx.cpp', + ['kmx.cpp', '../emscripten_filesystem.cpp'], cpp_args: defns + warns, include_directories: [inc, libsrc, '../../kmx_test_source'], link_args: links + tests_flags, objects: [lib.extract_all_objects(recursive: false), kmx_test_source_lib.extract_all_objects(recursive: false)]) tests = [ - '000 - null keyboard', - '001 - basic input UnicodeI', - '002 - basic input Unicode', - '003 - nul', - '004 - basic input (shift 2)', - '005 - nul with initial context', - '006 - vkey input (shift ctrl)', - '007 - vkey input (ctrl alt)', - '008 - vkey input (ctrl alt 2)', - '012 - ralt', - '013 - deadkeys', - '014 - groups and virtual keys', - '015 - ralt 2', - '017 - space mnemonic kbd', - '018 - nul testing', - '019 - multiple deadkeys', - '020 - deadkeys and backspace', - - '021 - options', - '022 - options with preset', - '023 - options with save', - '024 - options with save and preset', - '025 - options with reset', - - '026 - system stores', - '027 - system stores 2', + 'k_000___null_keyboard', + 'k_001___basic_input_unicodei', + 'k_002___basic_input_unicode', + 'k_003___nul', + 'k_004___basic_input__shift_2_', + 'k_005___nul_with_initial_context', + 'k_006___vkey_input__shift_ctrl_', + 'k_007___vkey_input__ctrl_alt_', + 'k_008___vkey_input__ctrl_alt_2_', + 'k_012___ralt', + 'k_013___deadkeys', + 'k_014___groups_and_virtual_keys', + 'k_015___ralt_2', + 'k_017___space_mnemonic_kbd', + 'k_018___nul_testing', + 'k_019___multiple_deadkeys', + 'k_020___deadkeys_and_backspace', + 'k_021___options', + 'k_022___options_with_preset', + 'k_023___options_with_save', + 'k_024___options_with_save_and_preset', + 'k_025___options_with_reset', + 'k_026___system_stores', + 'k_027___system_stores_2', + 'k_028___smp', + 'k_029___beep', + 'k_030___multiple_groups', + 'k_031___caps_lock', + 'k_032___caps_control', + 'k_033___caps_always_off', + 'k_034___options_double_set_reset', + 'k_035___options_double_set_staged', + 'k_036___options___double_reset_staged', + 'k_037___options___double_reset', + 'k_038___punctkeys', + 'k_039___generic_ctrlalt', + 'k_040___long_context', + 'k_041___long_context_and_deadkeys', + 'k_042___long_context_and_split_deadkeys', + 'k_043___output_and_keystroke', + 'k_044___if_and_context', + 'k_045___deadkey_and_context', + 'k_046___deadkey_and_contextex', + 'k_047___caps_always_off_initially_on', + 'k_048___modifier_keys_keep_context' +] - '028 - smp', - '029 - beep', +node = find_program('node', required: true) - '030 - multiple groups', - '031 - caps lock', - '032 - caps control', - '033 - caps always off', - '034 - options double set reset', - '035 - options double set staged', - '036 - options - double reset staged', - '037 - options - double reset', - '038 - punctkeys', - '039 - generic ctrlalt', - '040 - long context', - '041 - long context and deadkeys', - '042 - long context and split deadkeys', - '043 - output and keystroke', - - '044 - if and context', - '045 - deadkey and context', - '046 - deadkey and contextex', - '047 - caps always off initially on', - '048 - modifier keys keep context' -] +kmc_root = meson.current_source_dir() / '../../../../developer/src/kmc/build/src/kmc.js' +kmc_cmd = [node, kmc_root] if build_machine.system() == 'windows' - kmcomp = find_program(join_paths(meson.current_source_dir(),'..','..','..','..','windows','bin','developer','kmcomp.exe'), 'kmcomp.exe', required: false) - kmcomp_cmd = [kmcomp] copy_cmd = [find_program('cmd.exe', required: true), '/c', 'copy'] cat_cmd = [find_program('cmd.exe', required: true), '/c', 'type'] else - kmcomp = find_program('kmcomp', required: false) - kmcomp_cmd = [kmcomp] - if not kmcomp.found() - wine = find_program('wine', required: false) - kmcomp = find_program('kmcomp.exe', required: false) - kmcomp_cmd = [wine, kmcomp] - if not wine.found() - kmcomp = disabler() - endif - endif copy_cmd = [find_program('cp', required: true)] cat_cmd = [find_program('cat', required: true)] endif -if compiler.get_id() == 'emscripten' - # The .kmx files are linked in to the unit test, - # so kmcomp is too late here - kmcomp = disabler() -endif - test_keyboards = '' foreach kbd : tests if test_keyboards.startswith('{') test_keyboards += ''', ''' endif - kbd_basename = 'k_' + kbd.underscorify().to_lower() test_keyboards += '''{ - "name": "''' + kbd_basename + '''", - "id": "''' + kbd_basename + '''", + "name": "''' + kbd + '''", + "id": "''' + kbd + '''", "version": "0.0", "languages": [ { @@ -132,18 +111,6 @@ foreach kbd : tests } ] }''' - if not kmcomp.found() - configure_file( - command: copy_cmd + ['@INPUT@', '@OUTPUT@'], - input: kbd + '.kmn', - output: kbd_basename + '.kmn' - ) - configure_file( - command: copy_cmd + ['@INPUT@', '@OUTPUT@'], - input: kbd + '.kmx', - output: kbd_basename + '.kmx' - ) - endif endforeach cfg = configuration_data() @@ -154,69 +121,47 @@ configure_file( output: 'kmp.json' ) -if kmcomp.found() - foreach kbd : tests - kbd_basename = 'k_' + kbd.underscorify().to_lower() - - content = run_command( - cat_cmd, files(kbd + '.kmn'), - ).stdout().strip() - - cfg = configuration_data() - cfg.set('keyboard', kbd) - cfg.set('keyboard_underscore', kbd_basename) - cfg.set('id1', 'id_' + kbd_basename + '_1') - cfg.set('id2', 'id_' + kbd_basename + '_2') - cfg.set('id3', 'id_' + kbd_basename + '_3') - cfg.set('build_dir', meson.current_build_dir()) - cfg.set('NAME', kbd) - cfg.set('CONTENT', content) - - kbd_kmn = configure_file( - configuration: cfg, - input: join_paths('template', 'keyboard.kmn.in'), - output: kbd_basename + '.kmn' - ) - kbd_kpj = configure_file( - configuration: cfg, - input: join_paths('template', 'keyboard.kpj.in'), - output: kbd_basename + '.kpj' - ) - kbd_kps = configure_file( - configuration: cfg, - input: join_paths('template', 'keyboard.kps.in'), - output: kbd_basename + '.kps' - ) - kbd_kmp = custom_target(kbd_basename + '.kmp', - input: kbd_kpj, - output: [kbd_basename + '.kmp', kbd_basename + '.kmx'], - depend_files: [kbd_kps, kbd_kmn], - depfile: kbd_basename + '.dep', - command: kmcomp_cmd + ['-s', '-d', '@INPUT@']) - - kbd_src = files(join_paths(test_path, kbd_basename) + '.kmn') - kbd_obj = join_paths(test_path, kbd_basename) + '.kmx' - # kbd_log = custom_target(kbd.underscorify() + '.kmx', - # output: kbd + '.log', - # input: kbd_src, - # command: kmcomp_cmd + ['-s', '-d', '@INPUT@', kbd_obj, '@OUTPUT@'] - # ) - - test(kbd, kmx, depends: [kbd_kmp], args: [kbd_src, kbd_obj]) - endforeach -else - foreach kbd : tests - if compiler.get_id() == 'emscripten' - kbd_basename = kbd - else - kbd_basename = 'k_' + kbd.underscorify().to_lower() - endif - kbd_src = join_paths(test_path, kbd_basename) + '.kmn' - kbd_obj = join_paths(test_path, kbd_basename) + '.kmx' - - test(kbd, kmx, args: [kbd_src, kbd_obj]) - endforeach -endif +foreach kbd : tests + kbd_src_path = common_test_keyboards_baseline / kbd + '.kmn' + + content = run_command( + cat_cmd, files(kbd_src_path), + ).stdout().strip() + + cfg = configuration_data() + cfg.set('keyboard', kbd) + cfg.set('keyboard_underscore', kbd) + cfg.set('id1', 'id_' + kbd + '_1') + cfg.set('id2', 'id_' + kbd + '_2') + cfg.set('id3', 'id_' + kbd + '_3') + cfg.set('build_dir', meson.current_build_dir()) + cfg.set('NAME', kbd) + cfg.set('CONTENT', content) + + kbd_kmn = configure_file( + copy: true, + input: kbd_src_path, + output: kbd + '.kmn' + ) + kbd_kpj = configure_file( + configuration: cfg, + input: join_paths('template', 'keyboard.kpj.in'), + output: kbd + '.kpj' + ) + kbd_kps = configure_file( + configuration: cfg, + input: join_paths('template', 'keyboard.kps.in'), + output: kbd + '.kps' + ) + kbd_kmp = custom_target(kbd + '.kmp', + input: kbd_kpj, + output: [kbd + '.kmp', kbd + '.kmx'], + depend_files: [kbd_kps, kbd_kmn], + depfile: kbd + '.dep', + command: kmc_cmd + ['build', '--debug', '--no-compiler-version', '@INPUT@']) + + test(kbd, kmx, depends: [kbd_kmp], args: [test_path / kbd + '.kmn', test_path / kbd + '.kmx']) +endforeach # binary file unit tests @@ -229,48 +174,37 @@ subdir('fixtures') # should work for Linux, macOS, and WASM. test_path = source_path -key_e = executable('key_list', 'kmx_key_list.cpp', +key_e = executable('key_list', ['kmx_key_list.cpp', '../emscripten_filesystem.cpp'], cpp_args: defns + warns, include_directories: [inc, libsrc], link_args: links + tests_flags, objects: lib.extract_all_objects(recursive: false)) test_kbd = 'kmx_key_list' -if kmcomp.found() - kbd_src = files(test_kbd + '.kmn') - kbd_obj = join_paths(meson.current_source_dir(), test_kbd) + '.kmx' - kbd_log = custom_target(test_kbd + '.kmx'.underscorify(), - output: test_kbd + '.log', - input: kbd_src, - command: kmcomp_cmd + ['-s', '-d', '@INPUT@', kbd_obj, '@OUTPUT@'] - ) - test('key_list', key_e, depends: kbd_log, args: [kbd_obj] ) -else - kbd_obj = join_paths(test_path, test_kbd) + '.kmx' - test('key_list', key_e, args: [kbd_obj] ) -endif + +kbd_src = files(test_kbd + '.kmn') +kbd_obj = join_paths(meson.current_build_dir(), test_kbd) + '.kmx' +kbd_log = custom_target(test_kbd + '.kmx'.underscorify(), + output: test_kbd + '.log', + input: kbd_src, + command: kmc_cmd + ['build', '--debug', '--no-compiler-version', '@INPUT@', '--out-file', kbd_obj] +) +test('key_list', key_e, depends: kbd_log, args: [kbd_obj] ) # test for imx list -imx_e = executable('imx_list', 'kmx_imx.cpp', +imx_e = executable('imx_list', ['kmx_imx.cpp', '../emscripten_filesystem.cpp'], cpp_args: defns + warns, include_directories: [inc, libsrc], link_args: links + tests_flags, objects: lib.extract_all_objects(recursive: false)) test_kbd = 'kmx_imsample' -if kmcomp.found() - kbd_src = files(test_kbd + '.kmn') - kbd_obj = join_paths(meson.current_source_dir(), test_kbd) + '.kmx' - kbd_log = custom_target(test_kbd + '.kmx'.underscorify(), - output: test_kbd + '.log', - input: kbd_src, - command: kmcomp_cmd + ['-s', '-d', '@INPUT@', kbd_obj, '@OUTPUT@'] - ) - test('imx_list', imx_e, depends: kbd_log, args: [kbd_obj] ) -else - kbd_obj = join_paths(test_path, test_kbd) + '.kmx' - test('imx_list', imx_e, args: [kbd_obj] ) -endif - - +kbd_src = files(test_kbd + '.kmn') +kbd_obj = join_paths(meson.current_build_dir(), test_kbd) + '.kmx' +kbd_log = custom_target(test_kbd + '.kmx'.underscorify(), + output: test_kbd + '.log', + input: kbd_src, + command: kmc_cmd + ['build', '--debug', '--no-compiler-version', '@INPUT@', '--out-file', kbd_obj] +) + test('imx_list', imx_e, depends: kbd_log, args: [kbd_obj] ) diff --git a/core/tests/unit/kmx/template/keyboard.kpj.in b/core/tests/unit/kmx/template/keyboard.kpj.in index ba612eccaaa73de22774bdd6a0a1e93b45526fce..4c49cfe418d1dcc868fe36ce66c3eaa0b6f8b225 100644 --- a/core/tests/unit/kmx/template/keyboard.kpj.in +++ b/core/tests/unit/kmx/template/keyboard.kpj.in @@ -2,9 +2,9 @@ $PROJECTPATH - false - false - false + False + False + False keyboard diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp index 26210ab2f3b487fc45ecc7c9f8915fa474ac38e6..6308625c0cd1fdef7fc6e95d4193a7ebc34b3acb 100644 --- a/core/tests/unit/ldml/ldml.cpp +++ b/core/tests/unit/ldml/ldml.cpp @@ -21,8 +21,8 @@ #include "state.hpp" #include "utfcodec.hpp" -#include "../test_assert.h" -#include "../test_color.h" +#include +#include #include // for surrogate pair macros diff --git a/core/tests/unit/ldml/ldml_test_source.cpp b/core/tests/unit/ldml/ldml_test_source.cpp index fa7afa15ebdaca5ac06b71f6a54d0528230bb19c..817116bf9788416fee79f223e3a583489ab457a7 100644 --- a/core/tests/unit/ldml/ldml_test_source.cpp +++ b/core/tests/unit/ldml/ldml_test_source.cpp @@ -45,7 +45,7 @@ namespace km { namespace tests { -#include "../test_color.h" +#include LdmlTestSource::LdmlTestSource() { diff --git a/core/tests/unit/ldml/meson.build b/core/tests/unit/ldml/meson.build index 6ef36cc5e89d88e992bfbda3b67e4d0a6c7ecb7e..8a0c3c4ec4961b28b115db02cee635bd0dc11fc2 100644 --- a/core/tests/unit/ldml/meson.build +++ b/core/tests/unit/ldml/meson.build @@ -4,7 +4,8 @@ # Authors: Marc Durdin # -if compiler.get_id() == 'gcc' or compiler.get_id() == 'clang' or compiler.get_id() == 'emscripten' +# TODO -- why are these differing from the standard.meson.build flags? +if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' or cpp_compiler.get_id() == 'emscripten' warns = [ '-Wno-missing-field-initializers', '-Wno-unused-parameter' @@ -37,7 +38,7 @@ endif # Build ldml test executable -if compiler.get_id() == 'emscripten' +if cpp_compiler.get_id() == 'emscripten' tests_flags = ['--embed-file', join_paths(meson.current_build_dir(),'keyboards','@')] tests_flags += ['--embed-file', join_paths(meson.current_build_dir(),'invalid-keyboards','@')] test_path = '/' diff --git a/core/tests/unit/ldml/test_kmx_plus.cpp b/core/tests/unit/ldml/test_kmx_plus.cpp index 9518c0bd787a3ef1e0f1a6e1e1b0dcd8a4bc9ed3..d0ed53b683461ec759616bdbd723850aa072cc72 100644 --- a/core/tests/unit/ldml/test_kmx_plus.cpp +++ b/core/tests/unit/ldml/test_kmx_plus.cpp @@ -1,4 +1,4 @@ -#include "../test_assert.h" +#include #include "kmx/kmx_plus.h" #include "kmx/kmx_xstring.h" #include "../../../src/ldml/ldml_vkeys.hpp" diff --git a/developer/src/Makefile b/developer/src/Makefile index b2059a0cd99612af630d8435fa24ce97ece5a2df..c1ab53cce037f3cf9f48a8a8a0e523c24b034ea1 100644 --- a/developer/src/Makefile +++ b/developer/src/Makefile @@ -3,9 +3,9 @@ # !ifdef NODELPHI -TARGETS=build-tools kmcmpdll kmanalyze kmdecomp server kmc +TARGETS=build-tools kmcmplib kmcmpdll kmanalyze kmdecomp server kmc !else -TARGETS=build-tools kmcmpdll kmcomp kmanalyze kmconvert tike samples setup inst kmdecomp server kmc +TARGETS=build-tools kmcmplib kmcmpdll kmcomp kmanalyze kmconvert tike samples setup inst kmdecomp server kmc !endif EXCLUDEPATHDEFINES=1 @@ -29,7 +29,11 @@ imsample: .virtual cd $(DEVELOPER_ROOT)\src\imsample $(MAKE) $(TARGET) -kmcmpdll: .virtual +kmcmplib: global-versions .virtual + cd $(DEVELOPER_ROOT)\src\kmcmplib + $(MAKE) $(TARGET) + +kmcmpdll: kmcmplib .virtual cd $(DEVELOPER_ROOT)\src\kmcmpdll $(MAKE) $(TARGET) @@ -65,7 +69,7 @@ server: .virtual cd $(DEVELOPER_ROOT)\src\server $(MAKE) $(TARGET) -kmc: kmc-keyboard kmc-model kmc-model-info kmc-package +kmc: kmc-keyboard kmc-kmn kmc-model kmc-model-info kmc-package cd $(DEVELOPER_ROOT)\src\kmc $(MAKE) $(TARGET) @@ -73,6 +77,10 @@ kmc-keyboard: .virtual cd $(DEVELOPER_ROOT)\src\kmc-keyboard $(MAKE) $(TARGET) +kmc-kmn: .virtual + cd $(DEVELOPER_ROOT)\src\kmc-kmn + $(MAKE) $(TARGET) + kmc-model: .virtual cd $(DEVELOPER_ROOT)\src\kmc-model $(MAKE) $(TARGET) @@ -249,7 +257,7 @@ build-tools: global-versions: cd $(COMMON_ROOT) - @if not exist $(KEYMAN_ROOT)\common\windows\cpp\include\keymanversion_build.h $(MAKE) global-versions + @if not exist $(KEYMAN_ROOT)\include\keymanversion_build.h $(MAKE) global-versions cd $(DEVELOPER_ROOT)\src build-tools-internal: diff --git a/developer/src/common/delphi/compiler/compile.pas b/developer/src/common/delphi/compiler/compile.pas index ba136af97308b88f502837f14e9f0135a2cf1770..9b304b39d83d5dd75687a441ce4c054c9e570628 100644 --- a/developer/src/common/delphi/compiler/compile.pas +++ b/developer/src/common/delphi/compiler/compile.pas @@ -64,7 +64,7 @@ type FILE_KEY = record Key: WCHAR; // WCHAR -- actually a WORD - packing: WORD; + LineStoreIndex: WORD; Line: DWORD; ShiftFlags: DWORD; dpOutput: PWideChar; // from start of key structure @@ -174,6 +174,7 @@ type TCompilerOptions = record dwSize: DWORD; ShouldAddCompilerVersion: BOOL; + UseKmcmpLib: BOOL; end; COMPILER_OPTIONS = TCompilerOptions; diff --git a/developer/src/ext/json-schema-validator/json-validator.cpp b/developer/src/ext/json-schema-validator/json-validator.cpp index 8e8ffaee68c9b6cef878a78e6c4d0003f39368a0..28988f37b54d4e96ca0666f4c2c7dddcd723bc56 100644 --- a/developer/src/ext/json-schema-validator/json-validator.cpp +++ b/developer/src/ext/json-schema-validator/json-validator.cpp @@ -683,8 +683,8 @@ void json_validator::validate_object(const json &instance, const json &schema, c static std::size_t utf8_length(const std::string &s) { size_t len = 0; - for (const unsigned char &c : s) - if ((c & 0xc0) != 0x80) + for (const char &c : s) + if (((unsigned char)c & 0xc0) != 0x80) len++; return len; } diff --git a/developer/src/kmc-keyboard/build.sh b/developer/src/kmc-keyboard/build.sh index e6ac49b35dacaf06bc73eb9e981d9b09d2fc5eb5..d4e7f269ff347d9c3124e9d753174b529bd081a6 100755 --- a/developer/src/kmc-keyboard/build.sh +++ b/developer/src/kmc-keyboard/build.sh @@ -99,7 +99,7 @@ fi if builder_start_action publish; then copy_schemas - . "$KEYMAN_ROOT/resources/build/npm-publish.inc.sh" - npm_publish + . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" + builder_publish_to_npm builder_finish_action success publish fi diff --git a/developer/src/kmc-kmn/.gitignore b/developer/src/kmc-kmn/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6a608d487b85755178ab0c6f1367d719cdd61406 --- /dev/null +++ b/developer/src/kmc-kmn/.gitignore @@ -0,0 +1,3 @@ +# WASM interfaces from kmcmplib are copied here so we can avoid having +# to make tsc aware of debug vs release paths +src/import/ diff --git a/developer/src/kmc-kmn/Makefile b/developer/src/kmc-kmn/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..31ce8fcb9ca46bd8103dcdb74174eb46259a1948 --- /dev/null +++ b/developer/src/kmc-kmn/Makefile @@ -0,0 +1,37 @@ +# +# Keyman Developer - kmc kmn Compiler Makefile +# + +!include ..\Defines.mak + +build: .virtual + $(GIT_BASH_FOR_KEYMAN) build.sh build + +configure: .virtual + $(GIT_BASH_FOR_KEYMAN) build.sh configure + +clean: .virtual + $(GIT_BASH_FOR_KEYMAN) build.sh clean + +test: .virtual + $(GIT_BASH_FOR_KEYMAN) build.sh test + +# build.sh bundle must be run from shell as it requires a temp folder to be +# passed in. See inst/download.in.mak for instantiation. + +publish: .virtual + $(GIT_BASH_FOR_KEYMAN) build.sh publish + +signcode: + @rem nothing to do + +wrap-symbols: + @rem nothing to do + +test-manifest: + @rem nothing to do + +install: + @rem nothing to do + +!include ..\Target.mak diff --git a/developer/src/kmc-kmn/build.sh b/developer/src/kmc-kmn/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..033fadfe33bf46b5a94d8d9e01108b9814b795ac --- /dev/null +++ b/developer/src/kmc-kmn/build.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# +# Compiles the kmc-kmn keyboard compiler. +# + +# Exit on command failure and when using unset variables: +set -eu + +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../resources/build/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +cd "$THIS_SCRIPT_PATH" + +. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" + +builder_describe "Build Keyman Developer Compiler Module for .kmn to .kmx" \ + "@/common/web/keyman-version" \ + "@/common/web/types" \ + "@/developer/src/kmcmplib:wasm" \ + "configure" \ + "build" \ + "clean" \ + "test" \ + "publish publish to npm" \ + "--dry-run,-n don't actually publish, just dry run" + +builder_describe_outputs \ + configure /node_modules \ + build /developer/src/kmc-kmn/build/src/main.js + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +if builder_start_action clean; then + rm -rf ./build/ ./tsconfig.tsbuildinfo + builder_finish_action success clean +fi + +#------------------------------------------------------------------------------------------------------------------- + +if builder_start_action configure; then + verify_npm_setup + builder_finish_action success configure +fi + +#------------------------------------------------------------------------------------------------------------------- + +if builder_start_action build; then + mkdir -p build/src/import/kmcmplib + mkdir -p src/import/kmcmplib + cp ../kmcmplib/build/wasm/$BUILDER_CONFIGURATION/src/wasm-host.js ./src/import/kmcmplib/wasm-host.js + cp ../kmcmplib/build/wasm/$BUILDER_CONFIGURATION/src/wasm-host.wasm ./build/src/import/kmcmplib/wasm-host.wasm + tsc --build + builder_finish_action success build +fi + +#------------------------------------------------------------------------------------------------------------------- + +if builder_start_action test; then + npm test + builder_finish_action success test +fi + +#------------------------------------------------------------------------------------------------------------------- + +if builder_start_action publish; then + . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" + builder_publish_to_npm + builder_finish_action success publish +fi diff --git a/developer/src/kmc-kmn/package.json b/developer/src/kmc-kmn/package.json new file mode 100644 index 0000000000000000000000000000000000000000..5fa04ada45bc3e884c302609151724c5e1e728e3 --- /dev/null +++ b/developer/src/kmc-kmn/package.json @@ -0,0 +1,55 @@ +{ + "name": "@keymanapp/kmc-kmn", + "description": "Keyman Developer Compiler Module for .kmn to .kmx", + "keywords": [ + "keyboard", + "keyman", + "kmn", + "kmx", + "unicode" + ], + "type": "module", + "exports": { + ".": "./build/src/main.js" + }, + "scripts": { + "build": "tsc -b", + "test": "cd test && tsc -b && cd .. && c8 --reporter=lcov --reporter=text mocha", + "prepublishOnly": "npm run build" + }, + "author": "Marc Durdin (https://github.com/mcdurdin)", + "license": "MIT", + "bugs": { + "url": "https://github.com/keymanapp/keyman/issues" + }, + "dependencies": { + "@keymanapp/keyman-version": "*" + }, + "devDependencies": { + "@types/chai": "^4.1.7", + "@types/mocha": "^5.2.7", + "@types/node": "^10.14.6", + "@types/semver": "^7.3.12", + "@types/sinon": "^10.0.13", + "@types/sinon-chai": "^3.2.9", + "@types/xml2js": "^0.4.5", + "c8": "^7.12.0", + "chai": "^4.3.4", + "chalk": "^2.4.2", + "mocha": "^8.4.0", + "sinon": "^15.0.2", + "sinon-chai": "^3.7.0", + "ts-node": "^9.1.1", + "typescript": "^4.9.5" + }, + "mocha": { + "spec": "build/test/**/test-*.js", + "require": [ + "source-map-support/register" + ] + }, + "repository": { + "type": "git", + "url": "git+https://github.com/keymanapp/keyman.git" + } +} diff --git a/developer/src/kmc-kmn/src/compiler/compiler.ts b/developer/src/kmc-kmn/src/compiler/compiler.ts new file mode 100644 index 0000000000000000000000000000000000000000..a380c21e94bc7156e9b13ff8b8589c057f15744c --- /dev/null +++ b/developer/src/kmc-kmn/src/compiler/compiler.ts @@ -0,0 +1,93 @@ +/* +TODO: implement additional interfaces: + + extern "C" bool kmcmp_CompileKeyboardFileToBuffer( + char* pszInfile, + void* pfkBuffer, + bool ACompilerWarningsAsErrors, + bool AWarnDeprecatedCode, + kmcmp_CompilerMessageProc pMsgproc, + void* AmsgprocContext, + int Target + ); + + typedef bool (*kmcmp_ValidateJsonMessageProc)(int64_t offset, const char* szText, void* context); + + extern "C" bool kmcmp_ValidateJsonFile( + std::fstream& f, + std::fstream& fd, + kmcmp_ValidateJsonMessageProc MessageProc, + void* context + ); +*/ + +// TODO: rename wasm-host? +import loadWasmHost from '../import/kmcmplib/wasm-host.js'; + +export interface CompilerOptions { + shouldAddCompilerVersion?: boolean; + saveDebug?: boolean; + compilerWarningsAsErrors?: boolean; + warnDeprecatedCode?: boolean; +}; + +const baseOptions: CompilerOptions = { + shouldAddCompilerVersion: true, + saveDebug: true, + compilerWarningsAsErrors: false, + warnDeprecatedCode: true +}; + +export class Compiler { + wasmModule: any; + compileKeyboardFile: any; + setCompilerOptions: any; + + public async init(): Promise { + if(!this.wasmModule) { + this.wasmModule = await loadWasmHost(); + this.compileKeyboardFile = this.wasmModule.cwrap('kmcmp_Wasm_CompileKeyboardFile', 'number', ['string', 'string', + 'number', 'number', 'number', 'string']); + this.setCompilerOptions = this.wasmModule.cwrap('kmcmp_Wasm_SetCompilerOptions', 'number', ['number']); + } + return this.compileKeyboardFile !== undefined && this.setCompilerOptions !== undefined; + } + + public run(infile: string, outfile: string, options?: CompilerOptions): boolean { + if(!this.wasmModule) { + return false; + } + + options = {...baseOptions, ...options}; + + (globalThis as any).msgproc = function(line: number, code: number, msg: string) { + // TODO: link into the kmc error reporting infrastructure + console.log(`[${line}] ${code}: ${msg}`); + } + + // TODO: use callbacks for file access -- so kmc-kmn is entirely fs agnostic + let result = this.runCompiler(infile, outfile, options) == 1; + + (globalThis as any).msgproc = null; + + return result; + } + + private runCompiler(infile: string, outfile: string, options: CompilerOptions): number { + try { + if(!this.setCompilerOptions(options.shouldAddCompilerVersion)) { + console.error('Unable to set compiler options'); + } + return this.compileKeyboardFile( + infile, + outfile, + options.saveDebug ? 1 : 0, + options.compilerWarningsAsErrors ? 1 : 0, + options.warnDeprecatedCode ? 1 : 0, 'msgproc'); + } catch(e) { + // TODO: use sentry + console.error(e); + } + return 0; + } +} \ No newline at end of file diff --git a/developer/src/kmc-kmn/src/main.ts b/developer/src/kmc-kmn/src/main.ts new file mode 100644 index 0000000000000000000000000000000000000000..c3c3d6f17392b6a88880e2129d604a8036582210 --- /dev/null +++ b/developer/src/kmc-kmn/src/main.ts @@ -0,0 +1,2 @@ + +export { Compiler } from './compiler/compiler.js'; diff --git a/developer/src/kmc-kmn/test/README.md b/developer/src/kmc-kmn/test/README.md new file mode 100644 index 0000000000000000000000000000000000000000..96a198a0d33cfceb2154296d90b246744ea64107 --- /dev/null +++ b/developer/src/kmc-kmn/test/README.md @@ -0,0 +1,7 @@ +Keyman kmn Keyboard Compiler Tests +=================================== + +Test +---- + + ../build.sh test diff --git a/core/tests/unit/kmx/000 - null keyboard.kmn b/developer/src/kmc-kmn/test/fixtures/000.kmn similarity index 100% rename from core/tests/unit/kmx/000 - null keyboard.kmn rename to developer/src/kmc-kmn/test/fixtures/000.kmn diff --git a/developer/src/kmc-kmn/test/fixtures/000.kmx b/developer/src/kmc-kmn/test/fixtures/000.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a4bdc1b835ef1c3f0d0d71bfd66b513a0348feac Binary files /dev/null and b/developer/src/kmc-kmn/test/fixtures/000.kmx differ diff --git a/developer/src/kmc-kmn/test/test-compiler.ts b/developer/src/kmc-kmn/test/test-compiler.ts new file mode 100644 index 0000000000000000000000000000000000000000..7665d12f923c8614ffd0f190f41a954f5d942558 --- /dev/null +++ b/developer/src/kmc-kmn/test/test-compiler.ts @@ -0,0 +1,47 @@ +import 'mocha'; +import sinon from 'sinon'; +// import chai, { expect } from 'chai'; +import chai, { assert } from 'chai'; +import sinonChai from 'sinon-chai'; +import { Compiler } from '../src/main.js'; +import { dirname } from 'path'; +import { fileURLToPath } from 'url'; +import fs from 'fs'; + +const __dirname = dirname(fileURLToPath(import.meta.url)).replace(/\\/g, '/'); + +chai.use(sinonChai); + +describe('Compiler class', function() { + let consoleLog: any; + + beforeEach(function() { + consoleLog = sinon.spy(console, 'log'); + }); + + afterEach(function() { + consoleLog.restore(); + }); + + it('should start', async function() { + const compiler = new Compiler(); + assert(await compiler.init()); + }); + + it('should compile a basic keyboard', async function() { + const compiler = new Compiler(); + assert(await compiler.init()); + + const fixtureName = __dirname + '/../../test/fixtures/000.kmx'; + const infile = __dirname + '/../../test/fixtures/000.kmn'; + const outfile = __dirname + '/000.kmx'; + + assert(compiler.run(infile, outfile, {saveDebug: true, shouldAddCompilerVersion: false})); + + assert(fs.existsSync(outfile)); + const outfileData = fs.readFileSync(outfile); + const fixtureData = fs.readFileSync(fixtureName); + assert.equal(outfileData.byteLength, fixtureData.byteLength); + assert.deepEqual(outfileData, fixtureData); + }); +}); \ No newline at end of file diff --git a/developer/src/kmc-kmn/test/tsconfig.json b/developer/src/kmc-kmn/test/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..7d506d9fac565e0867f41f1131f07d50d3f1d337 --- /dev/null +++ b/developer/src/kmc-kmn/test/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../../kmc/tsconfig.kmc-base.json", + + "compilerOptions": { + "rootDir": ".", + "rootDirs": ["./", "../src/"], + "outDir": "../build/test", + "baseUrl": ".", + "allowSyntheticDefaultImports": true, // for chai + "paths": { + "@keymanapp/common-types": ["../../../../common/web/types/src/main"], + }, + }, + "include": [ + "**/test-*.ts", + "./helpers/index.ts" + ], + "references": [ + { "path": "../../../../common/web/keyman-version/tsconfig.esm.json" }, + { "path": "../../../../common/web/types/" }, + { "path": "../../../../common/tools/hextobin/" }, + { "path": "../" } + ] +} \ No newline at end of file diff --git a/developer/src/kmc-kmn/tsconfig.json b/developer/src/kmc-kmn/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..b828a5076487c095a83cfaf700f73801f44d758b --- /dev/null +++ b/developer/src/kmc-kmn/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.esm-base.json", + + "compilerOptions": { + "outDir": "build/src/", + "rootDir": "src/", + "baseUrl": ".", + "allowJs": true, + "paths": { + "@keymanapp/common-types": ["../../../common/web/types/src/main"], + }, + + }, + "include": [ + "src/**/*.ts", + "src/import/kmcmplib/wasm-host.js" + ], + "references": [ + { "path": "../../../common/web/keyman-version/tsconfig.esm.json" }, + { "path": "../../../common/web/types/" }, + ] +} diff --git a/developer/src/kmc-model-info/build.sh b/developer/src/kmc-model-info/build.sh index da212a417b286691faa0aecd84e441f82a49faf3..9ad828d1aa5d085b737d16c6956f49cb59c86f91 100755 --- a/developer/src/kmc-model-info/build.sh +++ b/developer/src/kmc-model-info/build.sh @@ -61,7 +61,7 @@ fi #------------------------------------------------------------------------------------------------------------------- if builder_start_action publish; then - . "$KEYMAN_ROOT/resources/build/npm-publish.inc.sh" - npm_publish + . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" + builder_publish_to_npm builder_finish_action success publish fi diff --git a/developer/src/kmc-model/build.sh b/developer/src/kmc-model/build.sh index 2582c10451e1987644d6c1989d1094573c184c27..5adbc0ba0c2f6bab80a0dc59f22b1a1d97ca37c9 100755 --- a/developer/src/kmc-model/build.sh +++ b/developer/src/kmc-model/build.sh @@ -67,7 +67,7 @@ fi #------------------------------------------------------------------------------------------------------------------- if builder_start_action publish; then - . "$KEYMAN_ROOT/resources/build/npm-publish.inc.sh" - npm_publish + . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" + builder_publish_to_npm builder_finish_action success publish fi diff --git a/developer/src/kmc-package/build.sh b/developer/src/kmc-package/build.sh index c17363729cb5b9ecc12c0463341f8bd447bb5b8e..dd99388877c193108b7eef43d9d2deceb3681d4c 100755 --- a/developer/src/kmc-package/build.sh +++ b/developer/src/kmc-package/build.sh @@ -60,7 +60,7 @@ fi #------------------------------------------------------------------------------------------------------------------- if builder_start_action publish; then - . "$KEYMAN_ROOT/resources/build/npm-publish.inc.sh" - npm_publish + . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" + builder_publish_to_npm builder_finish_action success publish fi diff --git a/developer/src/kmc/build.sh b/developer/src/kmc/build.sh index fd14e00e4cc74b9c23eac287762227c0657e9112..3c803e6d317f808fabd4743d2084b83cb614fffe 100755 --- a/developer/src/kmc/build.sh +++ b/developer/src/kmc/build.sh @@ -17,9 +17,11 @@ cd "$THIS_SCRIPT_PATH" . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" builder_describe "Build Keyman Keyboard Compiler kmc" \ + "@/common/include" \ "@/common/web/keyman-version" \ "@/common/web/types" \ "@/developer/src/kmc-keyboard" \ + "@/developer/src/kmc-kmn" \ "@/developer/src/kmc-model" \ "@/developer/src/kmc-model-info" \ "@/developer/src/kmc-package" \ @@ -37,6 +39,12 @@ builder_describe_outputs \ builder_parse "$@" +if builder_has_option --dry-run; then + DRY_RUN=--dry-run +else + DRY_RUN= +fi + #------------------------------------------------------------------------------------------------------------------- if builder_start_action clean; then @@ -91,14 +99,22 @@ fi #------------------------------------------------------------------------------------------------------------------- if builder_start_action publish; then - . "$KEYMAN_ROOT/resources/build/npm-publish.inc.sh" - npm_publish + . "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh" - # For now, kmc will have responsibility for publishing keyman-version. In - # the future, we should probably have a top-level npm publish script that - # publishes all modules for a given release version - # From: #7595 + # For now, kmc will have responsibility for publishing keyman-version and + # common-types, as well as all the other dependent modules. In the future, we + # should probably have a top-level npm publish script that publishes all + # modules for a given release version From: #7595 "$KEYMAN_ROOT/common/web/keyman-version/build.sh" publish $DRY_RUN + "$KEYMAN_ROOT/common/web/types/build.sh" publish $DRY_RUN + "$KEYMAN_ROOT/developer/src/kmc-keyboard/build.sh" publish $DRY_RUN + "$KEYMAN_ROOT/developer/src/kmc-kmn/build.sh" publish $DRY_RUN + "$KEYMAN_ROOT/developer/src/kmc-model/build.sh" publish $DRY_RUN + "$KEYMAN_ROOT/developer/src/kmc-model-info/build.sh" publish $DRY_RUN + "$KEYMAN_ROOT/developer/src/kmc-package/build.sh" publish $DRY_RUN + + # Finally, publish kmc + builder_publish_to_npm builder_finish_action success publish fi diff --git a/developer/src/kmc/src/activities/buildKmnKeyboard.ts b/developer/src/kmc/src/activities/buildKmnKeyboard.ts index 421c59c6138f5c7ceaa4a57a77cbcabfe5c65cea..40572dc0318b0bbf2965a9893204e47659ffa4a9 100644 --- a/developer/src/kmc/src/activities/buildKmnKeyboard.ts +++ b/developer/src/kmc/src/activities/buildKmnKeyboard.ts @@ -1,54 +1,43 @@ -import { spawnSync } from 'child_process'; import * as path from 'path'; import { BuildCommandOptions } from '../commands/build.js'; -import { getDeveloperBinPath } from '../util/getDeveloperBinPath.js'; +import { Compiler } from '@keymanapp/kmc-kmn'; +import { platform } from 'os'; export async function buildKmnKeyboard(infile: string, options: BuildCommandOptions): Promise { - // We'll call out to kmcomp.exe to build a .kmn keyboard into a .kmx Note: - // kmcomp.exe will also build a .js if it is required, and may not actually - // generate a .kmx if the output target defined in the .kmn is mobile/web - // only. kmcomp.exe will also build the .kvk file. - const binRoot = getDeveloperBinPath(); - if(binRoot == null) { - console.error('Could not locate Keyman Developer bin path'); + + let compiler = new Compiler(); + if(!await compiler.init()) { return false; } - let args = ['-nologo']; - if(options.debug) { - args.push('-d'); - } + // We need to resolve paths to absolute paths before calling kmc-kmn + let outfile = (options.outFile ?? infile).replace(/\.km.$/i, '.kmx'); + + infile = getPosixAbsolutePath(infile); + outfile = getPosixAbsolutePath(outfile); - args.push(path.win32.normalize(infile)); - - // .* target file name option allows us to specify .kmx output file and the - // .js output file will also be generated as required, in the same way as when - // we build a project. Note: this is a stop gap as we work to deprecate - // kmcomp.exe and replace it with kmcmp (cross-platform .kmx compiler in C++) - // + kmc-kmw (KMX->KMW transpiler in TypeScript) + kmc-kvk (KVK compiler in - // TypeScript). - let outfile = (options.outFile ?? infile).replace(/\\/g, '/'); - // For now, we normalize to posix, and then renormalize to win32 for launching - // kmcomp, until we have a cross-platform alternative to use - outfile = path.win32.normalize(options.outFile).replace(/\.km.$/i, '.*'); - args.push(outfile); - - const kmcomp = path.join(binRoot, 'kmcomp.exe'); - - // We won't attempt to make this call cross-platform, yet. - let child = spawnSync(kmcomp, args, { - encoding: 'utf8' + // TODO: Currently this only builds .kmn->.kmx, and targeting .js is as-yet unsupported + // TODO: Support additional options compilerWarningsAsErrors, warnDeprecatedCode + return compiler.run(infile, outfile, { + saveDebug: options.debug, + shouldAddCompilerVersion: options.compilerVersion, }); +} - if(child.error) { - console.error(child.error); - return false; +function getPosixAbsolutePath(filename: string): string { + if(platform() == 'win32') { + // On Win32, we need to use backslashes for path.resolve to work + filename = filename.replace(/\//g, '\\'); } - console.log(child.stdout); - if(child.stderr) { - console.error(child.stderr); - } + // Resolve to a fully qualified absolute path + filename = path.resolve(filename); - return child.status === 0; + if(platform() == 'win32') { + // Ensure that we convert the result back to posix-style paths which is what + // kmc-kmn expects. On posix platforms, we assume paths have forward slashes + // already + filename = filename.replace(/\\/g, '/'); + } + return filename; } \ No newline at end of file diff --git a/developer/src/kmcmpdll/Compiler.cpp b/developer/src/kmcmpdll/Compiler.cpp index 6289f95d11a008f5f637c76d841cc0e4ea27bb93..d7994d98b2ca5fe408bc212ff157dc6998954e40 100644 --- a/developer/src/kmcmpdll/Compiler.cpp +++ b/developer/src/kmcmpdll/Compiler.cpp @@ -90,6 +90,8 @@ #include "UnreachableRules.h" #include "CheckForDuplicates.h" +#include "../kmcmplib/include/kmcmplibapi.h" + int xatoi(PWSTR *p); int atoiW(PWSTR p); void safe_wcsncpy(PWSTR out, PWSTR in, int cbMax); @@ -214,6 +216,7 @@ BOOL FSaveDebug, FCompilerWarningsAsErrors, FWarnDeprecatedCode; // I4865 // BOOL FShouldAddCompilerVersion = TRUE; BOOL FOldCharPosMatching = FALSE, FMnemonicLayout = FALSE; NamedCodeConstants *CodeConstants = NULL; + int BeginLine[4]; /* Compile target */ @@ -288,21 +291,33 @@ BOOL AddCompileMessage(DWORD msg) return FALSE; } -typedef struct _COMPILER_OPTIONS { - DWORD dwSize; - BOOL ShouldAddCompilerVersion; -} COMPILER_OPTIONS; - -typedef COMPILER_OPTIONS *PCOMPILER_OPTIONS; +bool flag_use_new_kmcomp = true; // flag to switch to new kmcompx extern "C" BOOL __declspec(dllexport) SetCompilerOptions(PCOMPILER_OPTIONS options) { if(!options || options->dwSize < sizeof(COMPILER_OPTIONS)) { return FALSE; } + + flag_use_new_kmcomp = options->UseKmcmpLib; + + //printf("\n---> started in SetCompilerOptions() of kmcmpdll\n"); + if ( flag_use_new_kmcomp ) + { + KMCMP_COMPILER_OPTIONS kmcmp_options = {0}; + kmcmp_options.dwSize = sizeof(KMCMP_COMPILER_OPTIONS); + kmcmp_options.ShouldAddCompilerVersion = options->ShouldAddCompilerVersion; + return kmcmp_SetCompilerOptions(&kmcmp_options); + } + //printf("---> stayed in SetCompilerOptions() of kmcmpdll\n"); + FShouldAddCompilerVersion = options->ShouldAddCompilerVersion; return TRUE; } +int kmcmpMsgproc(int line, uint32_t dwMsgCode, char* szText, void* context) { + return static_cast(context)(line, dwMsgCode, szText); +} + extern "C" BOOL __declspec(dllexport) CompileKeyboardFile(PSTR pszInfile, PSTR pszOutfile, BOOL ASaveDebug, BOOL ACompilerWarningsAsErrors, BOOL AWarnDeprecatedCode, CompilerMessageProc pMsgProc) // I4865 // I4866 { HANDLE hInfile = INVALID_HANDLE_VALUE, hOutfile = INVALID_HANDLE_VALUE; @@ -310,6 +325,15 @@ extern "C" BOOL __declspec(dllexport) CompileKeyboardFile(PSTR pszInfile, PSTR p DWORD len; char str[260]; + //printf("\n---> started in CompileKeyboardFile() of kmcmpdll\n"); + + if ( flag_use_new_kmcomp ) + { + return kmcmp_CompileKeyboardFile(pszInfile, pszOutfile, ASaveDebug, ACompilerWarningsAsErrors,AWarnDeprecatedCode, kmcmpMsgproc, (void*) pMsgProc); + } + + //printf("---> stayed in CompileKeyboardFile() of kmcmpdll\n"); + FSaveDebug = ASaveDebug; FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 FWarnDeprecatedCode = AWarnDeprecatedCode; // I4866 @@ -331,6 +355,8 @@ extern "C" BOOL __declspec(dllexport) CompileKeyboardFile(PSTR pszInfile, PSTR p currentLine = 0; nErrors = 0; + AddCompileString("NOTE: Using legacy compiler"); + hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); @@ -392,6 +418,15 @@ extern "C" BOOL __declspec(dllexport) CompileKeyboardFileToBuffer(PSTR pszInfile DWORD len; char str[260]; + //printf("\n---> started in CompileKeyboardFileToBuffer() of kmcmpdll\n"); + if ( flag_use_new_kmcomp ) + { + return kmcmp_CompileKeyboardFileToBuffer( pszInfile, (void*) pfkBuffer, ACompilerWarningsAsErrors, AWarnDeprecatedCode, kmcmpMsgproc, (void*) pMsgProc, Target); + } + + //printf("---> stayed in CompileKeyboardFileToBuffer() of kmcmpdll\n"); + + FSaveDebug = TRUE; // I3681 FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 FWarnDeprecatedCode = AWarnDeprecatedCode; // I4866 @@ -413,6 +448,8 @@ extern "C" BOOL __declspec(dllexport) CompileKeyboardFileToBuffer(PSTR pszInfile currentLine = 0; nErrors = 0; + AddCompileString("NOTE: Using legacy compiler"); + hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); @@ -611,7 +648,6 @@ DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PWSTR p) if(BeginLine[BeginMode] != -1) { return CERR_RepeatedBegin; } - BeginLine[BeginMode] = currentLine; if ((msg = GetRHS(fk, p, tstr, 80, (int)(INT_PTR)(p - pp), FALSE)) != CERR_None) return msg; @@ -942,10 +978,23 @@ int cmpkeys(const void *key, const void *elem) { if (akey->Line < aelem->Line) return -1; if (akey->Line > aelem->Line) return 1; - return 0; + if(akey->Key == aelem->Key) { + if(akey->ShiftFlags == aelem->ShiftFlags) { + return akey->LineStoreIndex - aelem->LineStoreIndex; + } + return akey->ShiftFlags - aelem->ShiftFlags; + } + return akey->Key - aelem->Key; } if (l1 < l2) return 1; if (l1 > l2) return -1; + if(akey->Key == aelem->Key) { + if(akey->ShiftFlags == aelem->ShiftFlags) { + return akey->LineStoreIndex - aelem->LineStoreIndex; + } + return akey->ShiftFlags - aelem->ShiftFlags; + } + return akey->Key - aelem->Key; } return(char_key - char_elem); // akey->Key - aelem->Key); } @@ -1728,6 +1777,7 @@ CheckOutputIsReadonly(const PFILE_KEYBOARD fk, const PWSTR output) { // I4867 wcscpy_s(kp->dpContext, wcslen(pklIn) + 1, pklIn); // I3481 kp->Line = currentLine; + kp->LineStoreIndex = 0; // Finished if we are not using keys @@ -1869,6 +1919,7 @@ DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, DWORD storeIndex) k->ShiftFlags = 0; } k->Line = kpp->Line; + k->LineStoreIndex = (WORD)n; ExpandKp_ReplaceIndex(fk, k, keyIndex, n); } @@ -3315,6 +3366,7 @@ DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, HANDLE hOutfile) offset += gp->cxKeyArray * sizeof(COMP_KEY); for (j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) { + kp->_reserved = 0; kp->Key = fkp->Key; if (FSaveDebug) kp->Line = fkp->Line; else kp->Line = 0; kp->ShiftFlags = fkp->ShiftFlags; diff --git a/developer/src/kmcmpdll/Compiler.rc b/developer/src/kmcmpdll/Compiler.rc index d5b2e5289fbd2f423797ecb3c7342c0bc7e7eeb1..b1922ac9b431a202c45b31e5b59b3aadd3a419e4 100644 --- a/developer/src/kmcmpdll/Compiler.rc +++ b/developer/src/kmcmpdll/Compiler.rc @@ -91,12 +91,6 @@ END STRINGTABLE BEGIN CERR_InvalidSystemStore "Invalid system store name found" - CERR_CallIsProfessionalFeature - "Call() is only available in Keyman Developer Professional" - CERR_IncludeCodesIsProfessionalFeature - "&IncludeCodes is only available in Keyman Developer Professional" - CERR_MnemonicLayoutIsProfessionalFeature - "&MnemonicLayout is only available in Keyman Developer Professional" CERR_60FeatureOnly_VirtualCharKey "Virtual character keys require VERSION 6.0" CERR_VersionAlreadyIncluded diff --git a/developer/src/kmcmpdll/UnreachableRules.cpp b/developer/src/kmcmpdll/UnreachableRules.cpp index a5c6519ef323ffb771cfe46ff86e05100d29c538..84bff8752cf00b5541b36cc4821c7d4a2b0acfc1 100644 --- a/developer/src/kmcmpdll/UnreachableRules.cpp +++ b/developer/src/kmcmpdll/UnreachableRules.cpp @@ -16,7 +16,8 @@ std::wstring MakeHashKeyFromFileKey(PFILE_KEY kp) { std::wstringstream key; key << kp->Key << "," << kp->ShiftFlags << ","; - if (kp->dpContext) key << kp->dpContext; + if (kp->dpContext) + key << kp->dpContext; return key.str(); } diff --git a/developer/src/kmcmpdll/comperr.h b/developer/src/kmcmpdll/comperr.h index 258825dab4c8055ad8e1f3c417928d36ee8de235..3d1658af0ed8c99ee03e5c147cf9f4c6134ba3f2 100644 --- a/developer/src/kmcmpdll/comperr.h +++ b/developer/src/kmcmpdll/comperr.h @@ -101,9 +101,6 @@ #define CERR_InvalidNamedCode 0x0000403F #define CERR_InvalidSystemStore 0x00004040 -#define CERR_CallIsProfessionalFeature 0x00004041 -#define CERR_IncludeCodesIsProfessionalFeature 0x00004042 -#define CERR_MnemonicLayoutIsProfessionalFeature 0x00004043 #define CERR_60FeatureOnly_VirtualCharKey 0x00004044 #define CERR_VersionAlreadyIncluded 0x00004045 diff --git a/developer/src/kmcmpdll/compfile.h b/developer/src/kmcmpdll/compfile.h index f58e041830645e5979c7b8ba48b360a7a0d9d663..4fd6e68eb546a87d7f41ed22bca6421b36a13501 100644 --- a/developer/src/kmcmpdll/compfile.h +++ b/developer/src/kmcmpdll/compfile.h @@ -86,6 +86,7 @@ typedef FILE_STORE *PFILE_STORE; struct FILE_KEY { WCHAR Key; // WCHAR for consistency; only a byte used however + WORD LineStoreIndex; DWORD Line; DWORD ShiftFlags; PWSTR dpOutput; // from start of key structure diff --git a/developer/src/kmcmpdll/json-validation.cpp b/developer/src/kmcmpdll/json-validation.cpp index 9516925ad0d9969896d76069b42a590768c34d00..e35dc0485dcae1480b00b1f002bad5fa75b56d26 100644 --- a/developer/src/kmcmpdll/json-validation.cpp +++ b/developer/src/kmcmpdll/json-validation.cpp @@ -1,9 +1,14 @@ #include #include +#include "../kmcmplib/include/kmcmplibapi.h" #include +typedef bool (*kmcmp_ValidateJsonMessageProc)(int64_t offset, const char* szText, void* context); + +extern bool flag_use_new_kmcomp; + using nlohmann::json; using nlohmann::json_uri; using nlohmann::json_schema_draft4::json_validator; @@ -24,7 +29,19 @@ static void loader(const json_uri &uri, json &schema) } } +bool kmcmpMessageProc(int64_t offset, const char* szText, void* context) { + return ((ValidateJsonMessageProc)context)(offset, szText); +} + extern "C" BOOL __declspec(dllexport) ValidateJsonFile(PWSTR pwszSchemaFile, PWSTR pwszJsonFile, ValidateJsonMessageProc MessageProc) { + + if ( flag_use_new_kmcomp ) + { + std::fstream f(pwszSchemaFile); + std::fstream fd(pwszJsonFile); + return kmcmp_ValidateJsonFile(f, fd, kmcmpMessageProc, (void*)MessageProc); + } + std::fstream f(pwszSchemaFile); if (!f.good()) { MessageProc(-1, "Schema file could not be loaded."); diff --git a/developer/src/kmcmpdll/kmcmpdll.vcxproj b/developer/src/kmcmpdll/kmcmpdll.vcxproj index 9d6a5f192149ecbdaa830786c2ba48122b6c6d6c..384487cfcd5d1aa3f5fe941a96d87ba84682c92d 100644 --- a/developer/src/kmcmpdll/kmcmpdll.vcxproj +++ b/developer/src/kmcmpdll/kmcmpdll.vcxproj @@ -89,21 +89,25 @@ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(KEYMAN_ROOT)\developer\src\ext\json;$(KEYMAN_ROOT)\developer\src\ext\json-schema-validator $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(KEYMAN_ROOT)\developer\src\kmcmplib\build\x86\$(Configuration)\src;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) $(VC_IncludePath);$(WindowsSDK_IncludePath);$(KEYMAN_ROOT)\developer\src\ext\json;$(KEYMAN_ROOT)\developer\src\ext\json-schema-validator $(ProjectDir)obj\$(Platform)\$(Configuration)\ $(ProjectName).x64 $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(KEYMAN_ROOT)\developer\src\kmcmplib\build\x64\$(Configuration)\src;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) $(VC_IncludePath);$(WindowsSDK_IncludePath);$(KEYMAN_ROOT)\developer\src\ext\json;$(KEYMAN_ROOT)\developer\src\ext\json-schema-validator + $(KEYMAN_ROOT)\developer\src\kmcmplib\build\x86\$(Configuration)\src;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) $(VC_IncludePath);$(WindowsSDK_IncludePath);$(KEYMAN_ROOT)\developer\src\ext\json;$(KEYMAN_ROOT)\developer\src\ext\json-schema-validator $(ProjectDir)obj\$(Platform)\$(Configuration)\ $(ProjectName).x64 $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(KEYMAN_ROOT)\developer\src\kmcmplib\build\x64\$(Configuration)\src;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) @@ -138,7 +142,7 @@ $(KEYMAN_ROOT)\windows\src\global\inc - version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) + libkmcmplib.a;version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) true true @@ -186,7 +190,7 @@ $(KEYMAN_ROOT)\windows\src\global\inc - version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) + libkmcmplib.a;version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) true true Windows @@ -229,7 +233,7 @@ $(KEYMAN_ROOT)\windows\src\global\inc - version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) + libkmcmplib.a;version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) true true true @@ -273,7 +277,7 @@ $(KEYMAN_ROOT)\windows\src\global\inc - version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) + libkmcmplib.a;version.lib;setupapi.lib;iphlpapi.lib;imm32.lib;crypt32.lib;wintrust.lib;imagehlp.lib;ws2_32.lib;%(AdditionalDependencies) true true true diff --git a/developer/src/kmcmpdll/pch.h b/developer/src/kmcmpdll/pch.h index 473c0799a2edb47838fcbec0af7b810b444e933c..dcba976ea74dadadba3d36762e305c13a45f2cc9 100644 --- a/developer/src/kmcmpdll/pch.h +++ b/developer/src/kmcmpdll/pch.h @@ -11,12 +11,12 @@ #include #include -#include "../../../../common/windows/cpp/include/legacy_kmx_file.h" -#include "../../../../common/windows/cpp/include/xstring.h" +#include "../../../common/windows/cpp/include/legacy_kmx_file.h" +#include "../../../common/windows/cpp/include/xstring.h" -#include "../../../../common/windows/cpp/include/registry.h" -#include "../../../../common/windows/cpp/include/unicode.h" -#include "../../../../common/windows/cpp/include/crc32.h" +#include "../../../common/windows/cpp/include/registry.h" +#include "../../../common/windows/cpp/include/unicode.h" +#include "../../../common/windows/cpp/include/crc32.h" #include #include diff --git a/developer/src/kmcmplib/.gitignore b/developer/src/kmcmplib/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..9418ac1e3e286b280fc3efd20658b21cc98f277d --- /dev/null +++ b/developer/src/kmcmplib/.gitignore @@ -0,0 +1,4 @@ +build/ +wasm.build +tests/keyboards/ +resources/ \ No newline at end of file diff --git a/developer/src/kmcmplib/Makefile b/developer/src/kmcmplib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4acc7d3cfbf792efae24e4782debc9c6d61fd0b0 --- /dev/null +++ b/developer/src/kmcmplib/Makefile @@ -0,0 +1,39 @@ +# +# KMCmpLib Makefile +# + +!include ..\Defines.mak + +!ifdef GIT_BASH_FOR_KEYMAN +CALLER=$(GIT_BASH_FOR_KEYMAN) +!else +CALLER=start /wait +!endif +!ifdef DEBUG +BUILD_DEBUG=-d +!else +BUILD_DEBUG= +!endif + +build: .virtual + $(CALLER) ./build.sh clean configure build $(BUILD_DEBUG) + +clean: + $(CALLER) ./build.sh clean $(BUILD_DEBUG) + +signcode: + @rem Not required + +wrap-symbols: + @rem Not required + +test-manifest: + @rem This target needed as dependency for TIKE and KMCMPDLL + +test: + $(CALLER) ./build.sh test $(BUILD_DEBUG) + +install: + @rem Not required + +!include ..\Target.mak diff --git a/developer/src/kmcmplib/build.bat b/developer/src/kmcmplib/build.bat new file mode 100644 index 0000000000000000000000000000000000000000..7b5dcf110d82a93e380f7daf0a3c91202897a64e --- /dev/null +++ b/developer/src/kmcmplib/build.bat @@ -0,0 +1,121 @@ +@echo off +rem **************************************************************** +rem Run build.sh, not this file directly, to build on Windows. +rem **************************************************************** +setlocal enabledelayedexpansion + +if "%1"=="" goto help +if "%1"=="all" goto all +if "%1"=="x86" goto build +if "%1"=="x64" goto build + +echo "Invalid parameter." +goto help + +rem ---------------------------------- + +:help +echo Usage: %0 x86^|x64^|all debug^|release [configure] [build] [test] [additional params for meson/ninja] +echo or +echo Usage: %0 x86^|x64 -c +echo -c will leave your environment configured for Visual Studio for selected platform. +echo. +echo Otherwise, %0 is intended to be used by build.sh, not directly. +echo At least one of 'configure', 'build', or 'test' is required. +goto :eof + +rem ---------------------------------- + +:all + +setlocal +cd %KEYMAN_ROOT%\developer\src\kmcmplib +cmd /c build.bat x86 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + +cd %KEYMAN_ROOT%\developer\src\kmcmplib +cmd /c build.bat x64 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + +goto :eof + +rem ---------------------------------- + +:build + +set ARCH=%1 +shift + +if "%1"=="-c" goto :setup + +echo === Locating Visual Studio === + +rem From https://github.com/microsoft/vswhere +for /f "usebackq delims=#" %%a in (`"%programfiles(x86)%\Microsoft Visual Studio\Installer\vswhere" -latest -property installationPath`) do ( + set VsDevCmd_Path=%%a\Common7\Tools\VsDevCmd.bat +) + +if errorlevel 1 ( + echo vswhere failed [!errorlevel!] + exit /b !errorlevel! +) + +if not exist "!VsDevCmd_Path!" ( + echo Could not find vsdevcmd.bat [!VsDevCmd_Path!] + exit /b 1 +) + +echo === Configuring VC++ === +set VSCMD_SKIP_SENDTELEMETRY=1 +call "!VsDevCmd_Path!" -arch=!ARCH! -no_logo -startdir=none || exit !errorlevel! + +cd %KEYMAN_ROOT%\developer\src\kmcmplib + +set BUILDTYPE=%1 +shift + +set STATIC_LIBRARY=--default-library both + +set COMMAND=%1 +shift + +if "!COMMAND!" == "configure" ( + echo === Configuring Keyman KMX Compiler for Windows !ARCH! !BUILDTYPE! === + if exist build\!ARCH!\!BUILDTYPE! rd /s/q build\!ARCH!\!BUILDTYPE! + meson setup build\!ARCH!\!BUILDTYPE! !STATIC_LIBRARY! --buildtype !BUILDTYPE! --werror %1 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + shift +) + +if "!COMMAND!" == "build" ( + echo === Building Keyman KMX Compiler for Windows !ARCH! !BUILDTYPE! === + cd build\!ARCH!\!BUILDTYPE! || exit !errorlevel! + ninja %1 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + cd ..\..\.. + shift +) + +if "!COMMAND!" == "test" ( + echo === Testing Keyman KMX Compiler for Windows !ARCH! !BUILDTYPE! === + cd build\!ARCH!\!BUILDTYPE! || exit !errorlevel! + meson test --print-errorlogs %1 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + cd ..\..\.. + shift +) + +goto :eof + +rem ---------------------------------- + +:setup + +rem Standalone build, so we'll make the environment available to the caller +rem Also setup +rem Note: Visual Studio 2022 doesn't provide vcvarsall.bat, so we'll have to find a different solution +endlocal +for /f "usebackq delims=#" %%a in (`"%programfiles(x86)%\Microsoft Visual Studio\Installer\vswhere" -latest -property installationPath`) do ( + set VsDevCmd_Path=%%a\Common7\Tools\VsDevCmd.bat +) + +set VSCMD_SKIP_SENDTELEMETRY=1 +"!VsDevCmd_Path!" -arch=!ARCH! -no_logo -startdir=none +goto :eof + +rem ---------------------------------- diff --git a/developer/src/kmcmplib/build.sh b/developer/src/kmcmplib/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..68ed92b86922cb930df56fcab994a10a854ad2df --- /dev/null +++ b/developer/src/kmcmplib/build.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash + +set -e +set -u + +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../resources/build/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" +. "$THIS_SCRIPT_PATH/checkout-keyboards.inc.sh" +. "$THIS_SCRIPT_PATH/commands.inc.sh" + +cd "$THIS_SCRIPT_PATH" + +################################ Main script ################################ + +# +# Restrict available targets to those that can be built on the current system +# + +archtargets=(":wasm WASM build") + +case $BUILDER_OS in + win) + archtargets+=( + ":x86 32-bit Windows (x86) build" + ":x64 64-bit Windows (x64) build" + ) + ;; + mac|linux) + archtargets+=( + ":arch Linux or mac build -- current architecture" + ) + ;; +esac + +# TODO: consider using "linux" and "mac" instead of "arch"? +# ":linux Build for current Linux architecture" +# ":mac Build for current macOS architecture" + +builder_describe \ + "Build Keyman KMX Compiler Static Library +Libraries will be built in 'build///src'. + * : 'debug' or 'release' (see --debug flag) + * All parameters after '--' are passed to meson or ninja +" \ + "clean" \ + "configure" \ + "build" \ + "test" \ + "${archtargets[@]}" \ + "--test=opt_tests,-t test[s] to run (space separated)" + +builder_parse "$@" + +builder_describe_outputs \ + configure:x86 build/x86/$BUILDER_CONFIGURATION/build.ninja \ + configure:x64 build/x64/$BUILDER_CONFIGURATION/build.ninja \ + configure:arch build/arch/$BUILDER_CONFIGURATION/build.ninja \ + configure:wasm build/wasm/$BUILDER_CONFIGURATION/build.ninja \ + build:x86 build/x86/$BUILDER_CONFIGURATION/src/libkmcmplib.a \ + build:x64 build/x64/$BUILDER_CONFIGURATION/src/libkmcmplib.a \ + build:arch build/arch/$BUILDER_CONFIGURATION/src/libkmcmplib.a \ + build:wasm build/wasm/$BUILDER_CONFIGURATION/src/libkmcmplib.a + +TARGET_PATH="$THIS_SCRIPT_PATH/build" + +# Iterate through all possible targets; note that targets that cannot be built +# on the current platform have already been excluded through the archtargets +# settings above +targets=(wasm x86 x64 arch) + +do_action() { + local action_function=do_$1 + for target in "${targets[@]}"; do + MESON_PATH="$TARGET_PATH/$target/$BUILDER_CONFIGURATION" + $action_function $target + done +} + +locate_keyboards_repo + +# Note, we have a 'global' clean and also a per-arch clean +if builder_start_action clean; then + rm -rf "$THIS_SCRIPT_PATH/tests/keyboards" + builder_finish_action success clean +fi + +do_action clean + +# Note, we have a 'global' configure and also a per-arch configure +if builder_start_action configure; then + # Import our standard compiler defines; this is copied from + # /resources/build/meson/standard.meson.build by build.sh, because meson doesn't + # allow us to reference a file outside its root + mkdir -p "$THIS_SCRIPT_PATH/resources" + cp "$KEYMAN_ROOT/resources/build/meson/standard.meson.build" "$THIS_SCRIPT_PATH/resources/meson.build" + + # We have to checkout the keyboards repo in a 'configure' action because + # otherwise meson will not get the right list of keyboard source files, + # even though we only use it in the 'test' action + checkout_keyboards + builder_finish_action success configure +fi + +do_action configure + +do_action build +do_action test diff --git a/developer/src/kmcmplib/checkout-keyboards.inc.sh b/developer/src/kmcmplib/checkout-keyboards.inc.sh new file mode 100644 index 0000000000000000000000000000000000000000..defcb479ef4070a759b2767115d1949e7cc78ac1 --- /dev/null +++ b/developer/src/kmcmplib/checkout-keyboards.inc.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# +# Look for the keyboards repo, either at $KEYBOARDS_ROOT, or, if that is not +# set, prepare to clone from GitHub. It will always be cloned to ./keyboards/ +# +function locate_keyboards_repo() { + if [[ ! -f "$THIS_SCRIPT_PATH/tests/keyboards_commit_ref.txt" ]]; then + builder_die "keyboards_commit_ref.txt does not exist, run prep.sh" + fi + + if [[ ! -d "$THIS_SCRIPT_PATH/tests/fixtures" ]]; then + builder_die "fixtures folder does not exist, run prep.sh" + fi + + if [[ -z "${KEYBOARDS_ROOT+x}" ]]; then + # KEYBOARDS_ROOT is not set, so we'll clone from GitHub + export KEYBOARDS_SOURCE_REPO=https://github.com/keymanapp/keyboards + builder_echo warning "\$KEYBOARDS_ROOT variable not set, using $KEYBOARDS_SOURCE_REPO" + builder_echo warning "For faster test builds, setup a local clone of that repo and set" + builder_echo warning "\$KEYBOARDS_ROOT to point to it" + else + builder_echo "\$KEYBOARDS_ROOT variable is $KEYBOARDS_ROOT" + export KEYBOARDS_SOURCE_REPO="$KEYBOARDS_ROOT" + fi +} + +# +# Shallow-clone of keyboards repo at commit found in keyboards_commit_ref.txt +# +function checkout_keyboards() { + local KEYBOARDS_COMMIT=$(cat $THIS_SCRIPT_PATH/tests/keyboards_commit_ref.txt) + + mkdir -p "$THIS_SCRIPT_PATH/tests/keyboards" + pushd "$THIS_SCRIPT_PATH/tests/keyboards" > /dev/null + + if [[ ! -f "build.sh" ]]; then + # We'll have to init the folder and clone the repo + builder_echo "Checking out keyboards repository at $THIS_SCRIPT_PATH/tests/keyboards" + git init + git remote add origin "$KEYBOARDS_SOURCE_REPO" + fi + + # Make sure we have fetched the commit, as it may have changed + # from a previous build + builder_echo "Fetching commit $KEYBOARDS_COMMIT in repo at $THIS_SCRIPT_PATH/tests/keyboards" + git fetch --depth=1 --no-tags origin "$KEYBOARDS_COMMIT" + git reset --hard "$KEYBOARDS_COMMIT" + + popd > /dev/null +} diff --git a/developer/src/kmcmplib/commands.inc.sh b/developer/src/kmcmplib/commands.inc.sh new file mode 100644 index 0000000000000000000000000000000000000000..a0e172e2d135b00e92f11ea81f5a64386991d9d5 --- /dev/null +++ b/developer/src/kmcmplib/commands.inc.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env bash + +# ---------------------------------------------------------------------------- +# clean +# ---------------------------------------------------------------------------- + +do_clean() { + # clean: note build/ will be left, but build// should be gone + local target=$1 + builder_start_action clean:$target || return 0 + + rm -rf "$MESON_PATH" + builder_finish_action success clean:$target +} + +# ---------------------------------------------------------------------------- +# configure +# ---------------------------------------------------------------------------- + +do_configure() { + local target=$1 + builder_start_action configure:$target || return 0 + + local STANDARD_MESON_ARGS= + + if [[ $target == wasm ]]; then + # do_configure_wasm + locate_emscripten + build_meson_cross_file_for_wasm + STANDARD_MESON_ARGS="--cross-file wasm.defs.build --cross-file wasm.build --default-library static" + fi + + if [[ $target =~ ^(x86|x64)$ ]]; then + cmd //C build.bat $target $BUILDER_CONFIGURATION configure "${builder_extra_params[@]}" + else + pushd "$THIS_SCRIPT_PATH" > /dev/null + # Additional arguments are used by Linux build, e.g. -Dprefix=${INSTALLDIR} + meson setup "$MESON_PATH" --werror --buildtype $BUILDER_CONFIGURATION $STANDARD_MESON_ARGS "${builder_extra_params[@]}" + popd > /dev/null + fi + builder_finish_action success configure:$target +} + +# ---------------------------------------------------------------------------- +# build +# ---------------------------------------------------------------------------- + +do_build() { + local target=$1 + builder_start_action build:$target || return 0 + + if [[ $target =~ ^(x86|x64)$ ]]; then + # Build the meson targets, both x86 and x64 also + # We need to use a batch file here so we can get + # the Visual Studio build environment with vcvarsall.bat + # TODO: if PATH is the only variable required, let's try and + # eliminate this difference in the build process + cmd //C build.bat $target $BUILDER_CONFIGURATION build "${builder_extra_params[@]}" + else + pushd "$MESON_PATH" > /dev/null + ninja + popd > /dev/null + fi + builder_finish_action success build:$target +} + +# ---------------------------------------------------------------------------- +# test +# ---------------------------------------------------------------------------- + +do_test() { + local target=$1 + builder_start_action test:$target || return 0 + + # Works on a local clone of keyboards repository, to avoid clobbering + # user's existing keyboards repo, if present + checkout_keyboards + + if [[ $target =~ ^(x86|x64)$ ]]; then + cmd //C build.bat $target $BUILDER_CONFIGURATION test "${builder_extra_params[@]}" + else + pushd "$MESON_PATH" > /dev/null + meson test "${builder_extra_params[@]}" + popd > /dev/null + fi + builder_finish_action success test:$target +} + +# ---------------------------------------------------------------------------- +# install and uninstall +# ---------------------------------------------------------------------------- + +do_install() { + do_command install $1 +} + +do_uninstall() { + do_command uninstall $1 +} + +do_command() { + local command=$1 + local target=$2 + builder_start_action $command:$target || return 0 + pushd "$MESON_PATH" > /dev/null + ninja $command + popd > /dev/null + builder_finish_action success $command:$target +} + +# ---------------------------------------------------------------------------- +# utility functions +# ---------------------------------------------------------------------------- + +# +# We don't want to rely on emcc being on the path, because Emscripten puts far +# too many things onto the path (in particular for us, node). +# +# The following comment suggests that we don't need emcc on the path. +# https://github.com/emscripten-core/emscripten/issues/4848#issuecomment-1097357775 +# +# So we try and locate emcc in common locations ourselves. The search pattern +# is: +# +# 1. Look for $EMSCRIPTEN_BASE (our primary emscripten variable), which should +# point to the folder that emcc is located in +# 2. Look for $EMCC which should point to the emcc executable +# 3. Look for emcc on the path +# +locate_emscripten() { + if [[ -z ${EMSCRIPTEN_BASE+x} ]]; then + if [[ -z ${EMCC+x} ]]; then + local EMCC=`which emcc` + [[ -z $EMCC ]] && builder_die "locate_emscripten: Could not locate emscripten (emcc) on the path or with \$EMCC or \$EMSCRIPTEN_BASE" + fi + [[ -x $EMCC ]] || builder_die "locate_emscripten: Variable EMCC ($EMCC) does not point to a valid executable emcc" + EMSCRIPTEN_BASE="$(dirname "$EMCC")" + fi + + [[ -x ${EMSCRIPTEN_BASE}/emcc ]] || builder_die "locate_emscripten: Variable EMSCRIPTEN_BASE ($EMSCRIPTEN_BASE) does not point to emcc's folder" +} + +build_meson_cross_file_for_wasm() { + if [ $BUILDER_OS == win ]; then + local R=$(cygpath -w $(echo $EMSCRIPTEN_BASE) | sed 's_\\_\\\\_g') + else + local R=$(echo $EMSCRIPTEN_BASE | sed 's_/_\\/_g') + fi + sed -e "s/\$EMSCRIPTEN_BASE/$R/g" wasm.build.$BUILDER_OS.in > wasm.build +} \ No newline at end of file diff --git a/developer/src/kmcmplib/getversion.bat b/developer/src/kmcmplib/getversion.bat new file mode 100644 index 0000000000000000000000000000000000000000..dcab02e4d95e572491d8648757ed9fffa50e0850 --- /dev/null +++ b/developer/src/kmcmplib/getversion.bat @@ -0,0 +1,3 @@ +@echo off +REM Get the version number from VERSION.md +more ..\..\..\VERSION.md diff --git a/developer/src/kmcmplib/getversion.sh b/developer/src/kmcmplib/getversion.sh new file mode 100755 index 0000000000000000000000000000000000000000..cd02c07929fd1f8707c2ecfcb4f874a3d9373700 --- /dev/null +++ b/developer/src/kmcmplib/getversion.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# Get the version number from VERSION.md +VERSIONFILE=../../../VERSION.md +cat $VERSIONFILE diff --git a/developer/src/kmcmplib/include/keyman_version.h.in b/developer/src/kmcmplib/include/keyman_version.h.in new file mode 100644 index 0000000000000000000000000000000000000000..e55e7b70c745f32f547d79e322b0300450b58ee2 --- /dev/null +++ b/developer/src/kmcmplib/include/keyman_version.h.in @@ -0,0 +1,9 @@ +#define keyman_version_stringify(x) keyman_version_to_string(x) +#define keyman_version_to_string(x) #x + +// Product versioning + +#define KEYMAN_VERSION_MAJOR @majorver@ +#define KEYMAN_VERSION_MINOR @minorver@ +#define KEYMAN_VERSION_PATCH @patchver@ +#define KEYMAN_VERSION_STRING keyman_version_stringify(@majorver@ ## . ## @minorver@ ## . ## @patchver@ ## .0) diff --git a/developer/src/kmcmplib/include/kmcmplibapi.h b/developer/src/kmcmplib/include/kmcmplibapi.h new file mode 100644 index 0000000000000000000000000000000000000000..9cf28613fdfd694df097fcd7595d22f9a3ed6cd2 --- /dev/null +++ b/developer/src/kmcmplib/include/kmcmplibapi.h @@ -0,0 +1,60 @@ +#pragma once + +#include + +#ifdef __EMSCRIPTEN__ +#include +#else +#define EMSCRIPTEN_KEEPALIVE +#endif + +#ifdef __cplusplus +#define EXTERN extern "C" EMSCRIPTEN_KEEPALIVE +#else +#define EXTERN EMSCRIPTEN_KEEPALIVE +#endif + +typedef struct _KMCMP_COMPILER_OPTIONS { + uint32_t dwSize; + bool ShouldAddCompilerVersion; +} KMCMP_COMPILER_OPTIONS; + +EXTERN bool kmcmp_SetCompilerOptions( + KMCMP_COMPILER_OPTIONS* options +); + +typedef int (*kmcmp_CompilerMessageProc)(int line, uint32_t dwMsgCode, char* szText, void* context); + +EXTERN bool kmcmp_CompileKeyboardFile( + char* pszInfile, + char* pszOutfile, + bool ASaveDebug, + bool ACompilerWarningsAsErrors, + bool AWarnDeprecatedCode, + kmcmp_CompilerMessageProc pMsgproc, + void* AmsgprocContext +); + +/* Compile target */ + +#define CKF_KEYMAN 0 +#define CKF_KEYMANWEB 1 + +EXTERN bool kmcmp_CompileKeyboardFileToBuffer( + char* pszInfile, + void* pfkBuffer, + bool ACompilerWarningsAsErrors, + bool AWarnDeprecatedCode, + kmcmp_CompilerMessageProc pMsgproc, + void* AmsgprocContext, + int Target +); + +typedef bool (*kmcmp_ValidateJsonMessageProc)(int64_t offset, const char* szText, void* context); + +EXTERN bool kmcmp_ValidateJsonFile( + std::fstream& f, + std::fstream& fd, + kmcmp_ValidateJsonMessageProc MessageProc, + void* context +); diff --git a/developer/src/kmcmplib/include/kmcompx.h b/developer/src/kmcmplib/include/kmcompx.h new file mode 100644 index 0000000000000000000000000000000000000000..33a76beb743ec133db8858b9c8a93b1d9f9b57e3 --- /dev/null +++ b/developer/src/kmcmplib/include/kmcompx.h @@ -0,0 +1,49 @@ +#pragma once +#include + +// TODO: merge with kmcmplib.h + +typedef wchar_t KMX_WCHART; +typedef KMX_DWORD * PKMX_DWORD; +typedef char * PKMX_STR; +typedef KMX_WCHAR* PKMX_WCHAR ; + +// TODO: these defines are copied out of unicode.h, because unicode.h still +// has windows-specific types. These should be remerged at a future date + +#define Uni_IsSurrogate1(ch) ((ch) >= 0xD800 && (ch) <= 0xDBFF) +#define Uni_IsSurrogate2(ch) ((ch) >= 0xDC00 && (ch) <= 0xDFFF) +#define Uni_IsSMP(ch) ((ch) >= 0x10000) + +#define Uni_SurrogateToUTF32(ch, cl) (((ch) - 0xD800) * 0x400 + ((cl) - 0xDC00) + 0x10000) + +#define Uni_UTF32ToSurrogate1(ch) (((ch) - 0x10000) / 0x400 + 0xD800) +#define Uni_UTF32ToSurrogate2(ch) (((ch) - 0x10000) % 0x400 + 0xDC00) + +#define Uni_UTF16ToUTF32(p) (Uni_IsSurrogate1(*(p)) && Uni_IsSurrogate2(*((p)+1)) ? Uni_SurrogateToUTF32(*(p), *((p)+1)) : *(p)) + +// +// C++17 definition of Windows _countof +// TODO: remove use of _countof throughout +// + +#ifndef _MSC_VER +#include + +template < typename T, size_t N > +size_t _countof( T ( & arr )[ N ] ) +{ + return std::extent< T[ N ] >::value; +} + +#endif + +// For MSVC, we want to use the std CRT library functions +// and ignore security warnings at this time, so we are +// not forced to use the non-portable _s variants. +#define _CRT_SECURE_NO_DEPRECATE + +// strtok_s on MSVC works the same as strtok_r +#ifdef _MSC_VER +#define strtok_r strtok_s +#endif \ No newline at end of file diff --git a/developer/src/kmcmplib/include/meson.build b/developer/src/kmcmplib/include/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..6da312876345cbfd87f07e4387137d72bf54ccff --- /dev/null +++ b/developer/src/kmcmplib/include/meson.build @@ -0,0 +1,25 @@ +# +# Keyman is copyright (C) SIL International. MIT License. +# +# Cross platform build script to build headers +# + +project_ver = meson.project_version().split('.') + +cfg = configuration_data() +cfg.set('majorver', project_ver[0]) +cfg.set('minorver', project_ver[1]) +cfg.set('patchver', project_ver[2]) + +configure_file( + configuration: cfg, + input: 'keyman_version.h.in', + output: 'keyman_version.h', +) + +inc = include_directories( # '.', is_system: true) + '.', + '../../../../common/include', + '../../ext/json', + '../../ext/json-schema-validator' +) diff --git a/developer/src/kmcmplib/meson.build b/developer/src/kmcmplib/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..ae8fd6ac62130addd0b3a1a7642b1f4530571b4b --- /dev/null +++ b/developer/src/kmcmplib/meson.build @@ -0,0 +1,24 @@ +# +# Keyman is copyright (C) SIL International. MIT License. +# +# Cross platform build script to compile kmcmplib and tests +# + +project('kmcmplib', 'cpp', 'c', + version: run_command(find_program('getversion.bat', 'getversion.sh')).stdout().strip(), + license: 'MIT', + default_options : ['buildtype=release', + 'cpp_std=c++14', + 'b_vscrt=static_from_buildtype', + 'default_library=static']) + +# Import our standard compiler defines; this is copied from +# /resources/build/standard.meson.build by build.sh, because +# meson doesn't allow us to reference a file outside its root +subdir('resources') + +# ------------------------------------------------------------ + +subdir('include') +subdir('src') +subdir('tests') diff --git a/developer/src/kmcmplib/src/CasedKeys.cpp b/developer/src/kmcmplib/src/CasedKeys.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d832c4408c3d6913bf6bd1314ae0ac41a3421b4c --- /dev/null +++ b/developer/src/kmcmplib/src/CasedKeys.cpp @@ -0,0 +1,154 @@ + +#include "pch.h" + +#include "compfile.h" +#include "comperr.h" +#include "../../../../common/windows/cpp/include/vkeys.h" +#include "kmcmplib.h" + +#include "CharToKeyConversion.h" +#include "kmx_u16.h" +#include "xstring.h" + +namespace kmcmp { + extern KMX_BOOL FMnemonicLayout; // TODO: these globals should be consolidated one day +} + +KMX_DWORD ExpandCapsRule(PFILE_GROUP gp, PFILE_KEY kpp, PFILE_STORE sp); + +KMX_DWORD VerifyCasedKeys(PFILE_STORE sp) { + assert(sp != NULL); + + if (kmcmp::FMnemonicLayout) { + // The &CasedKeys system store is not supported for + // mnemonic layouts in 14.0 + return CERR_CasedKeysNotSupportedWithMnemonicLayout; + } + + // We will rewrite this store with virtual keys + + PKMX_WCHAR p = sp->dpString; + PKMX_WCHAR buf = new KMX_WCHAR[u16len(p) * 5 + 1]; // extended keys are 5 units long, so this is the max length + PKMX_WCHAR q = buf; + + while (*p) { + KMX_UINT key = 0, shift = 0; + if (*p != UC_SENTINEL) { + if (!kmcmp::MapUSCharToVK(*p, &key, &shift)) { + return CERR_CasedKeysMustContainOnlyVirtualKeys; + } + if (shift & K_SHIFTFLAG) { + return CERR_CasedKeysMustNotIncludeShiftStates; + } + } + else { + if (*(p + 1) != CODE_EXTENDED) { + return CERR_CasedKeysMustContainOnlyVirtualKeys; + } + shift = *(p + 2); + key = *(p + 3); + if (shift != ISVIRTUALKEY) { + return CERR_CasedKeysMustNotIncludeShiftStates; + } + } + *q++ = UC_SENTINEL; + *q++ = CODE_EXTENDED; + *q++ = shift; + *q++ = key; + *q++ = UC_SENTINEL_EXTENDEDEND; + *q = 0; + + p = incxstr(p); + } + + delete[] sp->dpString; + sp->dpString = buf; + + return CERR_None; +} + +KMX_DWORD ExpandCapsRulesForGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) { + assert(fk != NULL); + assert(gp != NULL); + + if (kmcmp::FMnemonicLayout) { + // The &CasedKeys system store is not supported for + // mnemonic layouts in 14.0 + return CERR_None; + } + + PFILE_STORE sp = FindSystemStore(fk, TSS_CASEDKEYS); + if (!sp) { + // If there is no &CasedKeys system store, then we do not + // process the key + return CERR_None; + } + + KMX_DWORD msg; + // ExpandCapsRule may add extra rules at the end of gp->dpKeyArray, + // reallocating it, so we (a) cache the original length, and (b) + // dereference the array every call + int cxKeyArray = gp->cxKeyArray; + for (int i = 0; i < cxKeyArray; i++) { + if ((msg = ExpandCapsRule(gp, &gp->dpKeyArray[i], sp)) != CERR_None) { + return msg; + } + } + return CERR_None; +} + +KMX_DWORD ExpandCapsRule(PFILE_GROUP gp, PFILE_KEY kpp, PFILE_STORE sp) { + KMX_UINT key = kpp->Key; + KMX_UINT shift = kpp->ShiftFlags; + + if (shift == 0) { + // Convert US key cap to a virtual key + if (!kmcmp::MapUSCharToVK(kpp->Key, &key, &shift)) { + return CERR_None; + } + } + + if (shift & (CAPITALFLAG | NOTCAPITALFLAG)) { + // Don't attempt expansion if either Caps Lock flag is specified in the key rule + return CERR_None; + } + + PKMX_WCHAR p = sp->dpString; + for (; *p; p = incxstr(p)) { + // We've already verified that the store contains only virtual keys in VerifyCasedKeys + if (*(p + 3) == key) { + break; + } + } + + if (!*p) { + // This key is not modified by Caps Lock + return CERR_None; + } + + // This key is modified by Caps Lock, so we need to duplicate this rule + PFILE_KEY k = new FILE_KEY[gp->cxKeyArray + 1]; + if (!k) return CERR_CannotAllocateMemory; + memcpy(k, gp->dpKeyArray, gp->cxKeyArray * sizeof(FILE_KEY)); + + kpp = &k[(int)(kpp - gp->dpKeyArray)]; + + delete gp->dpKeyArray; + gp->dpKeyArray = k; + gp->cxKeyArray++; + + k = &k[gp->cxKeyArray - 1]; + k->dpContext = new KMX_WCHAR[u16len(kpp->dpContext) + 1]; + k->dpOutput = new KMX_WCHAR[u16len(kpp->dpOutput) + 1]; + u16cpy(k->dpContext, kpp->dpContext ); // copy the context. + u16cpy(k->dpOutput, kpp->dpOutput ); // copy the output. + + k->Key = key; + k->Line = kpp->Line; + // Add the CAPITAL FLAG, invert shift flag for the rule + k->ShiftFlags = (shift ^ K_SHIFTFLAG) | CAPITALFLAG; + kpp->Key = key; + kpp->ShiftFlags = shift | NOTCAPITALFLAG; + + return CERR_None; +} diff --git a/developer/src/kmcmplib/src/CasedKeys.h b/developer/src/kmcmplib/src/CasedKeys.h new file mode 100644 index 0000000000000000000000000000000000000000..e97cc593898cd32b3dcb516bd4bb660b49f9ef6a --- /dev/null +++ b/developer/src/kmcmplib/src/CasedKeys.h @@ -0,0 +1,4 @@ +#pragma once + +KMX_DWORD VerifyCasedKeys(PFILE_STORE sp); +KMX_DWORD ExpandCapsRulesForGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp); diff --git a/developer/src/kmcmplib/src/CharToKeyConversion.cpp b/developer/src/kmcmplib/src/CharToKeyConversion.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0c2b652d095d57ed9a647e942902df00243e482b --- /dev/null +++ b/developer/src/kmcmplib/src/CharToKeyConversion.cpp @@ -0,0 +1,207 @@ + +#include "pch.h" +#include "CharToKeyConversion.h" + +/* Following VKeys come from Windows */ + +#define VK_COLON 0xBA +#define VK_EQUAL 0xBB +#define VK_COMMA 0xBC +#define VK_HYPHEN 0xBD +#define VK_PERIOD 0xBE +#define VK_SLASH 0xBF +#define VK_ACCENT 0xC0 +#define VK_LBRKT 0xDB +#define VK_BKSLASH 0xDC +#define VK_RBRKT 0xDD +#define VK_QUOTE 0xDE +#define VK_xDF 0xDF + +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD9 0x69 +#define VK_SPACE 0x20 + + +/* Following code lifted from syskbd.cpp and tweaked for compiler use. Todo: consolidate */ + +KMX_WCHAR kmcmp::VKToChar(KMX_WORD keyCode, KMX_UINT shiftFlags) +{ + KMX_CHAR shiftedDigit[] = ")!@#$%^&*("; + int n, Shift; + + if (!(shiftFlags & ISVIRTUALKEY)) return keyCode; + + if (shiftFlags & (LCTRLFLAG | RCTRLFLAG | LALTFLAG | RALTFLAG)) return 0; + + if (keyCode >= '0' && keyCode <= '9') + { + n = keyCode - '0'; + return ((shiftFlags & K_SHIFTFLAG) ? shiftedDigit[n] : keyCode); + } + + if (keyCode >= 'A' && keyCode <= 'Z') + { + Shift = (shiftFlags & K_SHIFTFLAG); + if (shiftFlags & (CAPITALFLAG)) Shift = !Shift; + return (Shift ? keyCode : keyCode + 32); + } + + if (keyCode >= VK_NUMPAD0 && keyCode <= VK_NUMPAD9) + { + if (!(shiftFlags & NUMLOCKFLAG)) return 0; + return keyCode - (VK_NUMPAD0 - '0'); + } + + Shift = (shiftFlags & K_SHIFTFLAG); + + switch (keyCode) + { + case VK_ACCENT: + return Shift ? '~' : '`'; + case VK_HYPHEN: + return Shift ? '_' : '-'; + case VK_EQUAL: + return Shift ? '+' : '='; + case VK_BKSLASH: + return Shift ? '|' : 92; + case VK_LBRKT: + return Shift ? '{' : '['; + case VK_RBRKT: + return Shift ? '}' : ']'; + case VK_COLON: + return Shift ? ':' : ';'; + case VK_QUOTE: + return Shift ? '"' : 39; + case VK_COMMA: + return Shift ? '<' : ','; + case VK_PERIOD: + return Shift ? '>' : '.'; + case VK_SLASH: + return Shift ? '?' : '/'; + case VK_SPACE: + return ' '; + } + return 0; + //keyCode; +} + + +/* This array is lifted from preservedkeymap.cpp */ +// TODO: share this +const struct +{ + KMX_UINT key; + KMX_BOOL shift; +} USCharMap[] = { + { VK_SPACE, FALSE }, // 20 ' ' + { '1', TRUE }, // 21 '!' + { VK_QUOTE, TRUE }, // 22 '"' + { '3', TRUE }, // 23 '#' + { '4', TRUE }, // 24 '$' + { '5', TRUE }, // 25 '%' + { '7', TRUE }, // 26 '&' + { VK_QUOTE, FALSE }, // 27 ''' + { '9', TRUE }, // 28 '(' + { '0', TRUE }, // 29 ')' + { '8', TRUE }, // 2A '*' + { VK_EQUAL, TRUE }, // 2B '+' + { VK_COMMA, FALSE }, // 2C ',' + { VK_HYPHEN, FALSE }, // 2D '-' + { VK_PERIOD, FALSE }, // 2E '.' + { VK_SLASH, FALSE }, // 2F '/' + + { '0', FALSE }, // 30 '0' + { '1', FALSE }, // 31 '1' + { '2', FALSE }, // 32 '2' + { '3', FALSE }, // 33 '3' + { '4', FALSE }, // 34 '4' + { '5', FALSE }, // 35 '5' + { '6', FALSE }, // 36 '6' + { '7', FALSE }, // 37 '7' + { '8', FALSE }, // 38 '8' + { '9', FALSE }, // 39 '9' + { VK_COLON, TRUE }, // 3A ':' + { VK_COLON, FALSE }, // 3B ';' + { VK_COMMA, TRUE }, // 3C '<' + { VK_EQUAL, FALSE }, // 3D '=' + { VK_PERIOD, TRUE }, // 3E '>' + { VK_SLASH, TRUE }, // 3F '?' + + { '2', TRUE }, // 40 '@' + { 'A', TRUE }, // 41 'A' + { 'B', TRUE }, // 42 'B' + { 'C', TRUE }, // 43 'C' + { 'D', TRUE }, // 44 'D' + { 'E', TRUE }, // 45 'E' + { 'F', TRUE }, // 46 'F' + { 'G', TRUE }, // 47 'G' + { 'H', TRUE }, // 48 'H' + { 'I', TRUE }, // 49 'I' + { 'J', TRUE }, // 4A 'J' + { 'K', TRUE }, // 4B 'K' + { 'L', TRUE }, // 4C 'L' + { 'M', TRUE }, // 4D 'M' + { 'N', TRUE }, // 4E 'N' + { 'O', TRUE }, // 4F 'O' + + { 'P', TRUE }, // 50 'P' + { 'Q', TRUE }, // 51 'Q' + { 'R', TRUE }, // 52 'R' + { 'S', TRUE }, // 53 'S' + { 'T', TRUE }, // 54 'T' + { 'U', TRUE }, // 55 'U' + { 'V', TRUE }, // 56 'V' + { 'W', TRUE }, // 57 'W' + { 'X', TRUE }, // 58 'X' + { 'Y', TRUE }, // 59 'Y' + { 'Z', TRUE }, // 5A 'Z' + { VK_LBRKT, FALSE }, // 5B '[' + { VK_BKSLASH, FALSE }, // 5C '\' + { VK_RBRKT, FALSE }, // 5D ']' + { '6', TRUE }, // 5E '^' + { VK_HYPHEN, TRUE }, // 5F '_' + + { VK_ACCENT, FALSE }, // 60 '`' + { 'A', FALSE }, // 61 'a' + { 'B', FALSE }, // 62 'b' + { 'C', FALSE }, // 63 'c' + { 'D', FALSE }, // 64 'd' + { 'E', FALSE }, // 65 'e' + { 'F', FALSE }, // 66 'f' + { 'G', FALSE }, // 67 'g' + { 'H', FALSE }, // 68 'h' + { 'I', FALSE }, // 69 'i' + { 'J', FALSE }, // 6A 'j' + { 'K', FALSE }, // 6B 'k' + { 'L', FALSE }, // 6C 'l' + { 'M', FALSE }, // 6D 'm' + { 'N', FALSE }, // 6E 'n' + { 'O', FALSE }, // 6F 'o' + + { 'P', FALSE }, // 70 'p' + { 'Q', FALSE }, // 71 'q' + { 'R', FALSE }, // 72 'r' + { 'S', FALSE }, // 73 's' + { 'T', FALSE }, // 74 't' + { 'U', FALSE }, // 75 'u' + { 'V', FALSE }, // 76 'v' + { 'W', FALSE }, // 77 'w' + { 'X', FALSE }, // 78 'x' + { 'Y', FALSE }, // 79 'y' + { 'Z', FALSE }, // 7A 'z' + { VK_LBRKT, TRUE }, // 7B '{' + { VK_BKSLASH, TRUE }, // 7C '|' + { VK_RBRKT, TRUE }, // 7D '}' + { VK_ACCENT, TRUE } // 7E '~' +}; + +KMX_BOOL kmcmp::MapUSCharToVK(KMX_UINT ch, KMX_UINT *puKey, KMX_UINT *puShiftFlags) { + assert(puKey != NULL); + assert(puShiftFlags != NULL); + if (ch >= 0x20 && ch < 0x7F) { + *puKey = USCharMap[ch - 0x20].key; + *puShiftFlags = ISVIRTUALKEY | (USCharMap[ch - 0x20].shift ? K_SHIFTFLAG : 0); + return TRUE; + } + return FALSE; +} diff --git a/developer/src/kmcmplib/src/CharToKeyConversion.h b/developer/src/kmcmplib/src/CharToKeyConversion.h new file mode 100644 index 0000000000000000000000000000000000000000..dd71ccbc0b1137027bec9ac46abd4904be562d12 --- /dev/null +++ b/developer/src/kmcmplib/src/CharToKeyConversion.h @@ -0,0 +1,6 @@ +#pragma once + +namespace kmcmp { + KMX_BOOL MapUSCharToVK(KMX_UINT ch, KMX_UINT *puKey, KMX_UINT *puShiftFlags); + KMX_WCHAR VKToChar(KMX_WORD keyCode, KMX_UINT shiftFlags); +} \ No newline at end of file diff --git a/developer/src/kmcmplib/src/CheckFilenameConsistency.cpp b/developer/src/kmcmplib/src/CheckFilenameConsistency.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f5fd26ba262b1d04d46ce1bb0a3cbe174996bbb --- /dev/null +++ b/developer/src/kmcmplib/src/CheckFilenameConsistency.cpp @@ -0,0 +1,145 @@ + +#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING 1 +#include "pch.h" +#include "compfile.h" +#include +#include "kmcmplib.h" +#include +#include "CheckFilenameConsistency.h" +#include "kmx_u16.h" +#include "filesystem.h" + +#ifdef _MSC_VER +#include +#endif + +namespace kmcmp { + extern KMX_CHAR CompileDir[260]; // TODO: this should not be a fixed buffer +} +bool IsRelativePath(KMX_CHAR const * p) { + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP + + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP + + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP + + if ((*p == '\\') || (*p == '/')) return FALSE; + if (*p && *(p + 1) == ':') return FALSE; + + return TRUE; +} + +bool IsRelativePath(KMX_WCHAR const * p) { + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP + + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP + + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP + + if ((*p == u'\\') || (*p == u'/'))return FALSE; + if (*p && *(p + 1) == u':') return FALSE; + + return TRUE; +} + +KMX_DWORD CheckFilenameConsistency( KMX_CHAR const * Filename, bool ReportMissingFile) { + PKMX_WCHAR WFilename = strtowstr(( KMX_CHAR *)Filename); + KMX_DWORD const result = CheckFilenameConsistency(WFilename, ReportMissingFile); + delete WFilename; + return result; +} + +KMX_DWORD CheckFilenameConsistency(KMX_WCHAR const * Filename, bool ReportMissingFile) { + // not ready yet: needs more attention-> common includes for non-Windows platforms + KMX_WCHAR Name[260]; // TODO: fixed buffer sizes bad + + + if (IsRelativePath(Filename)) { + PKMX_WCHAR WCompileDir = strtowstr(kmcmp::CompileDir); + u16ncpy(Name, WCompileDir, _countof(Name)); // I3481 + u16ncat(Name, Filename, _countof(Name)); // I3481 + delete[] WCompileDir; + } else { + u16ncpy(Name, Filename, _countof(Name)); // I3481 + } + +#ifndef _MSC_VER + // Filename consistency only needs to be checked on Windows, because other + // platforms are going to fail if the filename is inconsistent anyway! + if(!kmcmp_FileExists(Name)) { + if (ReportMissingFile) { + u16cpy(ErrExtraW, u"referenced file '"); + u16ncat(ErrExtraW, Filename, 256); + u16ncat(ErrExtraW, u"'", 256); + strcpy(ErrExtraLIB, string_from_u16string(ErrExtraW).c_str()); + AddWarning(CWARN_MissingFile); + } + return CERR_None; + } + return CERR_None; +#else + _wfinddata_t fi; + intptr_t n; + if ((n = _wfindfirst((const wchar_t*) Name, &fi)) == -1) { + if (ReportMissingFile) { + sprintf(ErrExtraLIB, "referenced file '%ls'", (wchar_t*) Filename); + AddWarning(CWARN_MissingFile); + } + return CERR_None; + } + + _findclose(n); + + KMX_WCHAR FName[_MAX_FNAME], Ext[_MAX_EXT]; + wchar_t WChName[_MAX_PATH]; + _wsplitpath_s((const wchar_t*)Filename, nullptr, 0, nullptr, 0, (wchar_t*) FName, _MAX_FNAME, (wchar_t*) Ext, _MAX_EXT); + _wmakepath_s(WChName, _MAX_PATH, nullptr, nullptr, (const wchar_t*) FName, (const wchar_t*) Ext); + if (wcscmp(WChName, fi.name) != 0) { + sprintf(ErrExtraLIB, "reference '%ls' does not match actual filename '%ls'", WChName, fi.name); + + AddWarning(CHINT_FilenameHasDifferingCase); + + } +#endif + + return CERR_None; +} + +KMX_DWORD CheckFilenameConsistencyForCalls(PFILE_KEYBOARD fk) { + // call() statements depend on a fairly ugly hack for js, + // where store(DllFunction) "my.dll:func" will look for a + // file called function.call_js. ( or should this be func.call_js ? ) + // This is ripe for rewrite! + // But let's check what we have anyway + + PFILE_STORE sp; + KMX_DWORD i, msg; + for (i = 0, sp = fk->dpStoreArray; i < fk->cxStoreArray; i++, sp++) { + if (!sp->fIsCall) continue; + + const std::u16string callsite(sp->dpString); + const auto colon = callsite.find(':'); + if (colon == std::u16string::npos) continue; + + auto func1 = callsite.substr(colon + 1); + std::u16string str_js(u".call_js"); + std::u16string func = func1+ str_js; + + if ((msg = CheckFilenameConsistency(func.c_str(), FALSE)) != CERR_None) { + return msg; + } + } + return CERR_None; +} diff --git a/developer/src/kmcmplib/src/CheckFilenameConsistency.h b/developer/src/kmcmplib/src/CheckFilenameConsistency.h new file mode 100644 index 0000000000000000000000000000000000000000..39f86db391b1ac6b870d7a521f297372059bd9b4 --- /dev/null +++ b/developer/src/kmcmplib/src/CheckFilenameConsistency.h @@ -0,0 +1,11 @@ +#pragma once + +#include "compfile.h" +#include "kmcmplib.h" + +KMX_DWORD CheckFilenameConsistencyForCalls(PFILE_KEYBOARD fk); +KMX_DWORD CheckFilenameConsistency(KMX_CHAR const * Filename, bool ReportMissingFile); +KMX_DWORD CheckFilenameConsistency(KMX_WCHAR const * Filename, bool ReportMissingFile); + +bool IsRelativePath(KMX_CHAR const * p); +bool IsRelativePath(KMX_WCHAR const * p); diff --git a/developer/src/kmcmplib/src/CheckForDuplicates.cpp b/developer/src/kmcmplib/src/CheckForDuplicates.cpp new file mode 100644 index 0000000000000000000000000000000000000000..11c995497fc4cb197c7b48825cda5f24ac736eac --- /dev/null +++ b/developer/src/kmcmplib/src/CheckForDuplicates.cpp @@ -0,0 +1,48 @@ + +#include "pch.h" + +#include "compfile.h" +#include +#include "kmcmplib.h" +#include +#include "kmx_u16.h" +#include + +#include "CheckForDuplicates.h" + +KMX_DWORD CheckForDuplicateGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) noexcept { + KMX_DWORD i; + PFILE_GROUP gp0 = fk->dpGroupArray; + for (i = 0; i < fk->cxGroupArray; i++, gp0++) { + if (gp0 == gp) { + continue; + } + if (u16icmp(gp0->szName, gp->szName) == 0) { + u16sprintf(ErrExtraW, 256, L" Group '%ls' declared on line %d", u16fmt(gp0->szName).c_str(), gp0->Line); + strcpy(ErrExtraLIB, string_from_u16string(ErrExtraW).c_str()); + return CERR_DuplicateGroup; + } + } + return CERR_None; +} + +KMX_DWORD CheckForDuplicateStore(PFILE_KEYBOARD fk, PFILE_STORE sp) noexcept { + if (!sp->szName[0]) { + // Stores with zero length names are reserved system stores. + // They cannot be defined in user code. This is not an issue. + return CERR_None; + } + KMX_DWORD i; + PFILE_STORE sp0 = fk->dpStoreArray; + for (i = 0; i < fk->cxStoreArray; i++, sp0++) { + if (sp0 == sp) { + continue; + } + if (u16icmp(sp0->szName, sp->szName) == 0) { + u16sprintf(ErrExtraW,256, L" Store '%ls' declared on line %d", u16fmt(sp0->szName).c_str(), sp0->line); + strcpy(ErrExtraLIB, string_from_u16string(ErrExtraW).c_str()); + return CERR_DuplicateStore; + } + } + return CERR_None; +} diff --git a/developer/src/kmcmplib/src/CheckForDuplicates.h b/developer/src/kmcmplib/src/CheckForDuplicates.h new file mode 100644 index 0000000000000000000000000000000000000000..20789dd5e2cdae8ab9c5ae7c7ba5a76e63518909 --- /dev/null +++ b/developer/src/kmcmplib/src/CheckForDuplicates.h @@ -0,0 +1,4 @@ +#pragma once + +KMX_DWORD CheckForDuplicateGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) noexcept; +KMX_DWORD CheckForDuplicateStore(PFILE_KEYBOARD fk, PFILE_STORE sp) noexcept; diff --git a/developer/src/kmcmplib/src/CheckNCapsConsistency.cpp b/developer/src/kmcmplib/src/CheckNCapsConsistency.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8b1a708d221912fbbe4b17b142c541ad70e1109b --- /dev/null +++ b/developer/src/kmcmplib/src/CheckNCapsConsistency.cpp @@ -0,0 +1,99 @@ + +#include "pch.h" + +#include +#include +#include +#include "CharToKeyConversion.h" + +/** + * If any rule uses CAPS or NCAPS for a given key, then every rule that + * uses that key must also use CAPS or NCAPS, as otherwise the results are + * inconsistent. For example, if Caps Lock is on, then [K_F] may still be + * matched: + * + * + [K_F] > 'foo' + * + [CAPS K_F] > 'bar' + * + * Because of the way that KeymanWeb compiles rules, this may even apply when + * we have a key rule that would otherwise be ignored due to context. In the + * following example, [Caps Lock] + [y] would result in no output (or default + * output) rather than 'bar', because the preceding rule would capture the + * Y key, ignoring Caps Lock, meaning that the subsequent rule would never + * even get tested. (Note that this was introduced in the KeymanWeb compiler + * fix for extremely long if/else ladders in Keyman 12 in #1561, and this is + * technically slightly inconsistent with Keyman Core, although in my analysis + * only in this already ambiguous situation. + * + * 'x' + [K_Y] > 'foo' + * [CAPS K_Y] > 'bar' + * + * Given all this, we'll warn any time we find a key that has inconsistent use + * of CAPS/NCAPS in its rules. + * + * @param fk Keyboard to check + */ +bool CheckNCapsConsistency(PFILE_KEYBOARD fk) { + struct CapsUsage { + int ncaps_line, caps_line, neither_line; + }; + + const int oldCurrentLine = kmcmp::currentLine; + + // 256 virtual key codes + sizeof the virtual key dictionary is max key code possible + const int nkeys = 256 + fk->cxVKDictionary; + auto caps_ncaps_usage = new CapsUsage [nkeys]; + + memset(caps_ncaps_usage, 0, nkeys * sizeof(CapsUsage)); + + PFILE_GROUP gp; + KMX_DWORD gn; + for (gn = 0, gp = fk->dpGroupArray; gn < fk->cxGroupArray; gn++, gp++) { + if (!gp->fUsingKeys) { + continue; + } + + PFILE_KEY kp; + KMX_DWORD kn; + for (kn = 0, kp = gp->dpKeyArray; kn < gp->cxKeyArray; kn++, kp++) { + KMX_UINT key; + KMX_UINT shift; + if (kp->ShiftFlags & ISVIRTUALKEY) { + if (kp->Key >= nkeys) { + assert(false); + continue; + } + key = kp->Key; + shift = kp->ShiftFlags; + } + else if (!kmcmp::MapUSCharToVK(kp->Key, &key, &shift)) { + // Not a valid key + continue; + } + + if (shift & NOTCAPITALFLAG) { + if (!caps_ncaps_usage[key].ncaps_line) caps_ncaps_usage[key].ncaps_line = (kp->Line == 0 ? 1 : kp->Line); + } + else if (shift & CAPITALFLAG) { + if (!caps_ncaps_usage[key].caps_line) caps_ncaps_usage[key].caps_line = (kp->Line == 0 ? 1 : kp->Line); + } + else { + if (!caps_ncaps_usage[key].neither_line) caps_ncaps_usage[key].neither_line = (kp->Line == 0 ? 1 : kp->Line); + } + } + } + + for (int i = 0; i < nkeys; i++) { + if (caps_ncaps_usage[i].neither_line && (caps_ncaps_usage[i].caps_line || caps_ncaps_usage[i].ncaps_line)) { + // We set the current line to one needing work: the developer should add the NCAPS flag + kmcmp::currentLine = caps_ncaps_usage[i].neither_line; + AddWarningBool(CWARN_KeyShouldIncludeNCaps); + } + } + + delete[] caps_ncaps_usage; + + kmcmp::currentLine = oldCurrentLine; + + return TRUE; +} diff --git a/developer/src/kmcmplib/src/CheckNCapsConsistency.h b/developer/src/kmcmplib/src/CheckNCapsConsistency.h new file mode 100644 index 0000000000000000000000000000000000000000..50fa744c4ac5819c648e7c21784f540c17edec96 --- /dev/null +++ b/developer/src/kmcmplib/src/CheckNCapsConsistency.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +bool CheckNCapsConsistency(PFILE_KEYBOARD fk); diff --git a/developer/src/kmcmplib/src/CompMsg.cpp b/developer/src/kmcmplib/src/CompMsg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2fa0d68322dc1217207bb8541a62e304fee40f76 --- /dev/null +++ b/developer/src/kmcmplib/src/CompMsg.cpp @@ -0,0 +1,158 @@ +#include + +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"}, + { 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"}, + { 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"}, + + { CHINT_FilenameHasDifferingCase , "Casing differences may fail on some platforms: "}, + { CHINT_UnreachableRule , "This rule will never be matched as another rule takes precedence"}, + + { 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_MissingFile , "The referenced file could not be found: "}, + + { 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; +} diff --git a/developer/src/kmcmplib/src/CompMsg.h b/developer/src/kmcmplib/src/CompMsg.h new file mode 100644 index 0000000000000000000000000000000000000000..38be6bd674d70ca500ec4f522372ae55735d6f1f --- /dev/null +++ b/developer/src/kmcmplib/src/CompMsg.h @@ -0,0 +1,5 @@ + +#include "km_types.h" +#include + +KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) ; diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d9600bd30be3030a02afc137401a1134e311a6d --- /dev/null +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -0,0 +1,3517 @@ +/* + Name: Compiler + Copyright: Copyright (C) SIL International. + Documentation: + Description: + Create Date: 20 Jun 2006 + + Modified Date: 25 Oct 2016 + Authors: mcdurdin + Related Files: + Dependencies: + + Bugs: + Todo: + Notes: + History: 20 Jun 2006 - mcdurdin - Initial version + 23 Aug 2006 - mcdurdin - Add VISUALKEYBOARD, KMW_RTL, KMW_HELPFILE, KMW_HELPTEXT, KMW_EMBEDJS system stores + 14 Sep 2006 - mcdurdin - Support icons in version 7 + 28 Sep 2006 - mcdurdin - Added product validation + 28 Sep 2006 - mcdurdin - Added test for version 7.0 icon support + 06 Oct 2006 - mcdurdin - Fix buffer overflow in UTF8 conversion + 04 Dec 2006 - mcdurdin - Fix readfile buffer bug + 04 Jan 2007 - mcdurdin - Add notany support + 22 Jan 2007 - mcdurdin - Add K_NPENTER reference + 25 Jan 2007 - mcdurdin - Resize buffers to 4095 + 30 May 2007 - mcdurdin - I786 - Compiler crash if zero length string in keystroke any + 23 Aug 2007 - mcdurdin - I1011 - Fix buffer clobbering for UTF8 conversion of large files + 27 Mar 2008 - mcdurdin - I1358 - Support for multiple languages for office config + 14 Jun 2008 - mcdurdin - Support documenting language id as a single WORD instead of by PRIMARY/SUB + 14 Jun 2008 - mcdurdin - Support Windows languages list + 28 Jul 2008 - mcdurdin - I1569 - line prefixes + 22 Mar 2010 - mcdurdin - Compiler fixup - x64 support + 25 May 2010 - mcdurdin - I1632 - Keyboard Options + 24 Jun 2010 - mcdurdin - I2432 - Use local buffers so GetXString can be re-entrant (used by if()) + 26 Jul 2010 - mcdurdin - I2467 - 8.0 renumber + 18 Mar 2011 - mcdurdin - I2646 - Compiler warning on invalid Ethnologue codes + 18 Mar 2011 - mcdurdin - I2525 - Unterminated string can crash compiler + 19 Jul 2011 - mcdurdin - I2993 - Named code constants cause a warning 0x208D to appear + 26 Jun 2012 - mcdurdin - I3377 - KM9 - Update code references from 8.0 to 9.0 + 17 Aug 2012 - mcdurdin - I3431 - V9.0 - Spaces in values in if comparisons break the compiler parser + 27 Aug 2012 - mcdurdin - I3439 - V9.0 - Refactor xstring support in C++ code + 27 Aug 2012 - mcdurdin - I3437 - V9.0 - Add support for set(&layer) and layer() + 27 Aug 2012 - mcdurdin - I3438 - V9.0 - Add support for custom virtual keys + 27 Aug 2012 - mcdurdin - I3430 - V9.0 - Add support for if(&platform) and if(&baselayout) to compilers + 27 Aug 2012 - mcdurdin - I3440 - V9.0 - Tidy up set statement delimiter recognition + 24 Oct 2012 - mcdurdin - I3483 - V9.0 - Add support for compiling in the layout file + 24 Oct 2012 - mcdurdin - I3481 - V9.0 - Eliminate unsafe calls in C++ + 24 Jan 2012 - mcdurdin - I3137 - If key part of VK rule is missing, compiler generates invalid file + 06 Feb 2012 - mcdurdin - I3228 - kmcmpdll sometimes tries to write temp files to Program Files + 03 Nov 2012 - mcdurdin - I3510 - V9.0 - Merge of I3228 - kmcmpdll sometimes tries to write temp files to Program Files + 03 Nov 2012 - mcdurdin - I3511 - V9.0 - Merge of I3137 - If key part of VK rule is missing, compiler generates invalid file + 13 Dec 2012 - mcdurdin - I3654 - V9.0 - Compiler appears to create unregistered keyboards even when registered + 13 Dec 2012 - mcdurdin - I3641 - V9.0 - compiler dll buffer overrun bugs + 13 Dec 2012 - mcdurdin - I3681 - V9.0 - KeymanWeb compiler should output formatted js when debug=1 + 13 Dec 2012 - mcdurdin - I3686 - V9.0 - AddStore attaches property flags to wrong store structure + 19 Mar 2014 - mcdurdin - I4140 - V9.0 - Add keyboard version information to keyboards + 04 Nov 2014 - mcdurdin - I4504 - V9.0 - Consolidate the compile action into single command + 02 Jul 2015 - mcdurdin - I4784 - Compiler does not recognise baselayout, layer or platform at the start of a line + 02 Jul 2015 - mcdurdin - I4785 - baselayout(), layer() and platform() produce incorrect compiled code + 24 Aug 2015 - mcdurdin - I4865 - Add treat hints and warnings as errors into project + 24 Aug 2015 - mcdurdin - I4866 - Add warn on deprecated features to project and compile + 24 Aug 2015 - mcdurdin - I4867 - Add test for code after use warning to compile + 06 Nov 2015 - mcdurdin - I4914 - kmcmpdll does not pick an index() statement that has an offset one past the key + 23 Feb 2016 - mcdurdin - I4982 - Defined character constants cannot be referenced correctly in other stores + 25 Oct 2016 - mcdurdin - I5135 - Remove product and licensing references from Developer projects +*/ +#include "pch.h" + +#include + +#include "compfile.h" +#include +#include "../../../../common/windows/cpp/include/vkeys.h" +#include +#include "versioning.h" +#include "kmcmplib.h" +#include "DeprecationChecks.h" + +#include "virtualcharkeys.h" + +// TODO: These three should be under common/cpp/include -- not windows specific +#include "../../../../common/windows/cpp/include/keymanversion.h" +#include "../../../../common/windows/cpp/include/crc32.h" +#include "../../../../common/windows/cpp/include/ConvertUTF.h" + +#include "debugstore.h" +#include "NamedCodeConstants.h" + +#include "xstring.h" + +#include "Edition.h" + +#include "CharToKeyConversion.h" +#include "CasedKeys.h" +#include +#include +#include "CheckFilenameConsistency.h" +#include "UnreachableRules.h" +#include "CheckForDuplicates.h" +#include "kmx_u16.h" +#include "filesystem.h" +#include + +/* These macros are adapted from winnt.h and legacy use only */ +#define MAKELANGID(p, s) ((((uint16_t)(s)) << 10) | (uint16_t)(p)) +#define PRIMARYLANGID(lgid) ((uint16_t)(lgid) & 0x3ff) +#define SUBLANGID(lgid) ((uint16_t)(lgid) >> 10) + + +using namespace kmcmp; + + char ErrExtraLIB[256]; + KMX_WCHAR ErrExtraW[256]; + KMX_BOOL AWarnDeprecatedCode_GLOBAL_LIB; + +namespace kmcmp{ + KMX_BOOL FShouldAddCompilerVersion = TRUE; + KMX_BOOL FSaveDebug, FCompilerWarningsAsErrors; // I4865 // I4866 + int ErrChr; + int nErrors = 0; + KMX_BOOL FMnemonicLayout = FALSE; + KMX_BOOL FOldCharPosMatching = FALSE; + int CompileTarget; + KMX_CHAR CompileDir[260]; // TODO: this should not be a fixed buffer + int BeginLine[4]; + + KMX_BOOL IsValidCallStore(PFILE_STORE fs); + KMX_BOOL CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall); + KMX_DWORD UTF32ToUTF16(int n, int *n1, int *n2); + KMX_DWORD CheckUTF16(int n); + int cmpkeys(const void *key, const void *elem); +} + +int xatoi(PKMX_WCHAR *p); +int atoiW(PKMX_WCHAR p); +void safe_wcsncpy(PKMX_WCHAR out, PKMX_WCHAR in, int cbMax); +int GetDeadKey(PFILE_KEYBOARD fk, PKMX_WCHAR p); + +KMX_BOOL IsSameToken(PKMX_WCHAR *p, KMX_WCHAR const * token); +KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode); +PKMX_WCHAR GetDelimitedString(PKMX_WCHAR *p, KMX_WCHAR const * Delimiters, KMX_WORD Flags); +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); + +int GetGroupNum(PFILE_KEYBOARD fk, PKMX_WCHAR p); + +KMX_DWORD AddDebugStore(PFILE_KEYBOARD fk, KMX_WCHAR const * str); +KMX_DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode); +KMX_DWORD ProcessEthnologueStore(PKMX_WCHAR p); // I2646 +KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk); +KMX_DWORD ImportBitmapFile(PFILE_KEYBOARD fk, PKMX_WCHAR szName, PKMX_DWORD FileSize, PKMX_BYTE *Buf); + +KMX_DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, KMX_DWORD storeIndex); + +int GetVKCode(PFILE_KEYBOARD fk, PKMX_WCHAR p); // I3438 // TODO: Consolidate GetDeadKey and GetVKCode? +KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp); + +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_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); +KMX_DWORD process_platform(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx); // I3430 +KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx); // I3430 +KMX_DWORD process_set_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx); // I3437 +KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx, int max); + +KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); + +const KMX_WCHAR * LineTokens[] = { + u"SVNBHBGMNSCCLLCMLB", u"store", u"VERSION ", u"NAME ", + u"BITMAP ", u"HOTKEY ", u"begin", u"group", u"match", u"nomatch", + u"SHIFT FREES CAPS", u"CAPS ON ONLY", u"CAPS ALWAYS OFF", + u"LANGUAGE ", u"LAYOUT ", u"COPYRIGHT ", u"MESSAGE ", u"LANGUAGENAME ", + u"BITMAPS " }; + +#define SSN__PREFIX u"&" + +const KMX_WCHAR * StoreTokens[TSS__MAX + 2] = { + u"", + SSN__PREFIX u"BITMAP", + SSN__PREFIX u"COPYRIGHT", + SSN__PREFIX u"HOTKEY", + SSN__PREFIX u"LANGUAGE", + SSN__PREFIX u"LAYOUT", + SSN__PREFIX u"MESSAGE", + SSN__PREFIX u"NAME", + SSN__PREFIX u"VERSION", + SSN__PREFIX u"CAPSONONLY", + SSN__PREFIX u"CAPSALWAYSOFF", + SSN__PREFIX u"SHIFTFREESCAPS", + SSN__PREFIX u"LANGUAGENAME", + u"", + u"", + SSN__PREFIX u"ETHNOLOGUECODE", + u"", + SSN__PREFIX u"MNEMONICLAYOUT", + SSN__PREFIX u"INCLUDECODES", + SSN__PREFIX u"OLDCHARPOSMATCHING", + u"", + u"", + u"", + u"", + SSN__PREFIX u"VISUALKEYBOARD", + SSN__PREFIX u"KMW_RTL", + SSN__PREFIX u"KMW_HELPFILE", + SSN__PREFIX u"KMW_HELPTEXT", + SSN__PREFIX u"KMW_EMBEDJS", + SSN__PREFIX u"WINDOWSLANGUAGES", + u"", + SSN__PREFIX u"PLATFORM", // read only // I3430 + SSN__PREFIX u"BASELAYOUT", // read only // I3430 + SSN__PREFIX u"LAYER", // read-write via set? // I3430 + u"", // I3438 + SSN__PREFIX u"LAYOUTFILE", // I3483 + SSN__PREFIX u"KEYBOARDVERSION", // I4140 + SSN__PREFIX u"KMW_EMBEDCSS", + SSN__PREFIX u"TARGETS", // I4504 + SSN__PREFIX u"CASEDKEYS", // #2241 + SSN__PREFIX u"", // TSS_BEGIN_NEWCONTEXT + SSN__PREFIX u"", // TSS_BEGIN_POSTKEYSTROKE + SSN__PREFIX u"NEWLAYER", + SSN__PREFIX u"OLDLAYER", + NULL +}; + +static_assert(sizeof(StoreTokens) / sizeof(StoreTokens[0]) == TSS__MAX + 2, "StoreTokens should have exactly TSS__MAX+2 elements"); + +enum LinePrefixType { lptNone, lptKeymanAndKeymanWeb, lptKeymanWebOnly, lptKeymanOnly, lptOther }; + +/* Compile target */ + +kmcmp_CompilerMessageProc msgproc = NULL; +void* msgprocContext = NULL; + +int kmcmp::currentLine = 0; + +kmcmp::NamedCodeConstants *kmcmp::CodeConstants = NULL; + +PKMX_WCHAR strtowstr(PKMX_STR in) +{ + PKMX_WCHAR result; + + auto c = u16string_from_string(in); + + result = new KMX_WCHAR[c.length() + 1]; + u16cpy(result, c.c_str()); + return result; +} + +PKMX_STR wstrtostr(PKMX_WCHAR in) +{ + PKMX_STR result; + + auto c = string_from_u16string(in); + + result = new KMX_CHAR[c.length() + 1]; + strcpy(result, c.c_str()); + return result; +} + +KMX_BOOL kmcmp::AddCompileWarning(PKMX_CHAR buf) +{ + (*msgproc)(kmcmp::currentLine + 1, CWARN_Info, buf, msgprocContext); + return FALSE; +} + +KMX_BOOL AddCompileError(KMX_DWORD msg) +{ + KMX_CHAR szText[SZMAX_ERRORTEXT + 1 + 280]; + KMX_CHAR* szTextp = NULL; + + if (msg & CERR_FATAL) + { + szTextp = GetCompilerErrorString(msg); + (*msgproc)(kmcmp::currentLine + 1, msg, szTextp, msgprocContext); + kmcmp::nErrors++; + return TRUE; + } + + if (msg & CERR_ERROR) + kmcmp::nErrors++; + szTextp = GetCompilerErrorString(msg); + + if (szTextp) { + strcpy(szText, szTextp); + } + else { + sprintf(szText, "Unknown error %x", msg); + } + + if (kmcmp::ErrChr > 0) + sprintf(strchr(szText, 0), " character offset: %d", kmcmp::ErrChr); + + if (*ErrExtraLIB) { + sprintf(strchr(szText, 0), "%s", ErrExtraLIB); + } + + ErrChr = 0; *ErrExtraLIB =0; + if (!(*msgproc)(kmcmp::currentLine, msg, szText, msgprocContext)) return TRUE; + return FALSE; +} + +KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +{ + KMX_WCHAR tstr[128]; + PKMX_WCHAR q, pp; + int BeginMode; + KMX_DWORD msg; + + pp = p; + + q = ( PKMX_WCHAR) u16chr(p, '>'); + if (!q) return CERR_NoTokensFound; + + while (iswspace(*p)) p++; + if (u16nicmp(p, u"unicode", 7) == 0) BeginMode = BEGIN_UNICODE; + else if (u16nicmp(p, u"ansi", 4) == 0) BeginMode = BEGIN_ANSI; + else if (u16nicmp(p, u"newContext", 10) == 0) BeginMode = BEGIN_NEWCONTEXT; + else if (u16nicmp(p, u"postKeystroke", 13) == 0) BeginMode = BEGIN_POSTKEYSTROKE; + else if (*p != '>') return CERR_InvalidToken; + else BeginMode = BEGIN_ANSI; + + if(kmcmp::BeginLine[BeginMode] != -1) { + return CERR_RepeatedBegin; + } + + kmcmp::BeginLine[BeginMode] = kmcmp::currentLine; + + if ((msg = GetRHS(fk, p, tstr, 80, (int)(p - pp), FALSE)) != CERR_None) return msg; + + if (tstr[0] != UC_SENTINEL || tstr[1] != CODE_USE) { + return CERR_InvalidBegin; + } + if (tstr[3] != 0) { + return CERR_InvalidToken; + } + + if (BeginMode == BEGIN_ANSI || BeginMode == BEGIN_UNICODE) { + fk->StartGroup[BeginMode] = tstr[2] - 1; + //mcd-03-01-2000: removed the secondary group idea; this was undocumented and + //is not supported under Keyman 5.0: ugly!! + //if(tstr[3] == UC_SENTINEL && tstr[4] == CODE_USE) fk->StartGroup[1] = tstr[5] - 1; + + if (kmcmp::FSaveDebug) { + /* Record a system store for the line number of the begin statement */ + AddDebugStore(fk, BeginMode == BEGIN_UNICODE ? DEBUGSTORE_BEGIN u"Unicode" : DEBUGSTORE_BEGIN u"ANSI"); + } + } + else { + PFILE_GROUP gp = &fk->dpGroupArray[tstr[2] - 1]; + if (!gp->fReadOnly) { + return BeginMode == BEGIN_NEWCONTEXT ? + CERR_NewContextGroupMustBeReadonly : + CERR_PostKeystrokeGroupMustBeReadonly; + } + return AddStore(fk, BeginMode == BEGIN_NEWCONTEXT ? TSS_BEGIN_NEWCONTEXT : TSS_BEGIN_POSTKEYSTROKE, tstr, NULL); + } + + + + return CERR_None; +} + +KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p) { + while (p && *p) { + if (*p == UC_SENTINEL) { + switch (*(p + 1)) { + case CODE_CONTEXT: + case CODE_CONTEXTEX: + case CODE_INDEX: + return CERR_ContextAndIndexInvalidInMatchNomatch; + } + } + p = incxstr(p); + } + return CERR_None; +} + +KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) +{ + PKMX_WCHAR p, q, pp; + PFILE_GROUP gp; + KMX_DWORD msg; + int IsUnicode = TRUE; // For NOW! + + KMX_WCHAR sep[2] = u"\n"; + PKMX_WCHAR p_sep =sep; + p = str; + pp = str; + + switch (LineTokenType(&p)) + { + case T_BLANK: + case T_COMMENT: + break; // Ignore the line + case T_VERSION: + case T_STORE: + break; // The line has already been processed + + case T_BEGIN: + // after a begin can be "Unicode" or "ANSI" or nothing (=ANSI) + if ((msg = ProcessBeginLine(fk, p)) != CERR_None) return msg; + break; + + case T_GROUP: + if (fk->currentGroup == 0xFFFFFFFF) fk->currentGroup = 0; + else + { + if ((msg = ProcessGroupFinish(fk)) != CERR_None) return msg; // finish off previous group first? + fk->currentGroup++; + } + // if( (err = ProcessGroupLine( fk, p )) != CERR_None ) return err; + break; + + case T_NAME: + kmcmp::WarnDeprecatedHeader(); // I4866 + q = GetDelimitedString(&p, u"\"\"", 0); + if (!q) return CERR_InvalidName; + + if ((msg = AddStore(fk, TSS_NAME, q)) != CERR_None) return msg; + break; + + case T_COPYRIGHT: + kmcmp::WarnDeprecatedHeader(); // I4866 + q = GetDelimitedString(&p, u"\"\"", 0); + if (!q) return CERR_InvalidCopyright; + + if ((msg = AddStore(fk, TSS_COPYRIGHT, q)) != CERR_None) return msg; + break; + + case T_MESSAGE: + kmcmp::WarnDeprecatedHeader(); // I4866 + q = GetDelimitedString(&p, u"\"\"", 0); + if (!q) return CERR_InvalidMessage; + + if ((msg = AddStore(fk, TSS_MESSAGE, q)) != CERR_None) return msg; + break; + + case T_LANGUAGENAME: + kmcmp::WarnDeprecatedHeader(); // I4866 + q = GetDelimitedString(&p, u"\"\"", 0); + if (!q) return CERR_InvalidLanguageName; + + if ((msg = AddStore(fk, TSS_LANGUAGENAME, q)) != CERR_None) return msg; + break; + + case T_LANGUAGE: + { + kmcmp::WarnDeprecatedHeader(); // I4866 + KMX_WCHAR *tokcontext = NULL; + q = u16tok(p, p_sep, &tokcontext); // I3481 + + if ((msg = AddStore(fk, TSS_LANGUAGE, q)) != CERR_None) return msg; + break; + } + case T_LAYOUT: + { + kmcmp::WarnDeprecatedHeader(); // I4866 + KMX_WCHAR *tokcontext = NULL; + q = u16tok(p, p_sep, &tokcontext); // I3481 + if ((msg = AddStore(fk, TSS_LAYOUT, q)) != CERR_None) return msg; + break; + } + case T_CAPSOFF: + kmcmp::WarnDeprecatedHeader(); // I4866 + if ((msg = AddStore(fk, TSS_CAPSALWAYSOFF, u"1")) != CERR_None) return msg; + break; + + case T_CAPSON: + kmcmp::WarnDeprecatedHeader(); // I4866 + if ((msg = AddStore(fk, TSS_CAPSONONLY, u"1")) != CERR_None) return msg; + break; + + case T_SHIFT: + kmcmp::WarnDeprecatedHeader(); // I4866 + if ((msg = AddStore(fk, TSS_SHIFTFREESCAPS, u"1")) != CERR_None) return msg; + break; + + case T_HOTKEY: + { + kmcmp::WarnDeprecatedHeader(); // I4866 + KMX_WCHAR *tokcontext = NULL; + if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) return CERR_CodeInvalidInThisSection; // I3481 + if ((msg = AddStore(fk, TSS_HOTKEY, q)) != CERR_None) return msg; + break; + } + case T_BITMAP: + { + kmcmp::WarnDeprecatedHeader(); // I4866 + KMX_WCHAR *tokcontext = NULL; + if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + + while (iswspace(*q)) q++; + if (*q == '"') { + p = q; + q = GetDelimitedString(&p, u"\"\"", 0); + if (!q) return CERR_InvalidBitmapLine; + } + + if ((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; + break; + } + case T_BITMAPS: + { + kmcmp::WarnDeprecatedHeader(); // I4866 + KMX_WCHAR *tokcontext = NULL; + AddWarning(CWARN_BitmapNotUsed); + + if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + + if ((PKMX_WCHAR) u16chr(q, ',')) *(PKMX_WCHAR) u16chr(q, ',') = 0; + if ((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; + + break; + } + case T_KEYTOKEY: // A rule + if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + if ((msg = ProcessKeyLine(fk, p, IsUnicode)) != CERR_None) return msg; + break; + + case T_MATCH: + if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + { + PKMX_WCHAR buf = new KMX_WCHAR[GLOBAL_BUFSIZE]; + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE - 1, (int)(p - pp), IsUnicode)) != CERR_None) + { + delete[] buf; + return msg; + } + + if ((msg = ValidateMatchNomatchOutput(buf)) != CERR_None) { + delete[] buf; + return msg; + } + + gp = &fk->dpGroupArray[fk->currentGroup]; + + gp->dpMatch = new KMX_WCHAR[u16len(buf) + 1]; + u16ncpy(gp->dpMatch, buf, u16len(buf) + 1); // I3481 + + delete[] buf; + + if (kmcmp::FSaveDebug) + { + KMX_WCHAR tstr[128]; + //swprintf(tstr, "%d", fk->currentGroup); + /* Record a system store for the line number of the begin statement */ + //wcscpy(tstr, DEBUGSTORE_MATCH); + u16sprintf(tstr, _countof(tstr), L"%ls%d ", u16fmt(DEBUGSTORE_MATCH).c_str(), (int) fk->currentGroup); + u16ncat(tstr, gp->szName, _countof(tstr)); + + AddDebugStore(fk, tstr); + } + } + break; + + case T_NOMATCH: + if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + { + PKMX_WCHAR buf = new KMX_WCHAR[GLOBAL_BUFSIZE]; + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE, (int)(p - pp), IsUnicode)) != CERR_None) + { + delete[] buf; + return msg; + } + + if ((msg = ValidateMatchNomatchOutput(buf)) != CERR_None) { + delete[] buf; + return msg; + } + + gp = &fk->dpGroupArray[fk->currentGroup]; + + gp->dpNoMatch = new KMX_WCHAR[u16len(buf) + 1]; + u16ncpy(gp->dpNoMatch, buf, u16len(buf) + 1); // I3481 + + delete[] buf; + + if (kmcmp::FSaveDebug) + { + KMX_WCHAR tstr[128]; + /* Record a system store for the line number of the begin statement */ + u16sprintf(tstr, _countof(tstr), L"%ls%d ", u16fmt(DEBUGSTORE_NOMATCH).c_str(), (int) fk->currentGroup); + u16ncat(tstr, gp->szName, _countof(tstr)); + AddDebugStore(fk, tstr); + } + } + break; + + default: + return CERR_InvalidToken; + } + + return CERR_None; +} + +//********************************************************************************************************************** + +KMX_DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +{ + PFILE_GROUP gp; + PKMX_WCHAR q; + + gp = new FILE_GROUP[fk->cxGroupArray + 1]; + if (!gp) return CERR_CannotAllocateMemory; + + if (fk->dpGroupArray) + { + memcpy(gp, fk->dpGroupArray, sizeof(FILE_GROUP) * fk->cxGroupArray); + delete fk->dpGroupArray; + } + + fk->dpGroupArray = gp; + gp = &fk->dpGroupArray[fk->cxGroupArray]; + fk->cxGroupArray++; + + gp->dpKeyArray = NULL; + gp->dpMatch = NULL; + gp->dpNoMatch = NULL; + gp->cxKeyArray = 0; + + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q) return CERR_InvalidGroupLine; + + gp->fUsingKeys = FALSE; + gp->fReadOnly = IsSameToken(&p, u"readonly"); + if (!gp->fReadOnly) { + if (IsSameToken(&p, u"using") && IsSameToken(&p, u"keys")) + gp->fUsingKeys = TRUE; + } + + safe_wcsncpy(gp->szName, q, SZMAX_GROUPNAME); + + gp->Line = kmcmp::currentLine; + + if (kmcmp::FSaveDebug) + { + KMX_WCHAR tstr[128]; + /* Record a system store for the line number of the begin statement */ + u16sprintf(tstr, _countof(tstr), L"%ls%d ", u16fmt(DEBUGSTORE_GROUP).c_str(), fk->cxGroupArray - 1); + u16ncat(tstr, gp->szName, _countof(tstr)); + AddDebugStore(fk, tstr); + } + + return CheckForDuplicateGroup(fk, gp); +} + +int kmcmp::cmpkeys(const void *key, const void *elem) +{ + PFILE_KEY akey; + PFILE_KEY aelem; + int l1, l2; + KMX_WCHAR char_key, char_elem; + akey = (PFILE_KEY)key; + aelem = (PFILE_KEY)elem; + char_key = kmcmp::VKToChar(akey->Key, akey->ShiftFlags); + char_elem = kmcmp::VKToChar(aelem->Key, aelem->ShiftFlags); + if (char_key == char_elem) //akey->Key == aelem->Key) + { + l1 = xstrlen(akey->dpContext); l2 = xstrlen(aelem->dpContext); + if (l1 == l2) + { + if (akey->Line < aelem->Line) return -1; + if (akey->Line > aelem->Line) return 1; + if(akey->Key == aelem->Key) { + if(akey->ShiftFlags == aelem->ShiftFlags) { + return akey->LineStoreIndex - aelem->LineStoreIndex; + } + return akey->ShiftFlags - aelem->ShiftFlags; + } + return akey->Key - aelem->Key; + } + if (l1 < l2) return 1; + if (l1 > l2) return -1; + if(akey->Key == aelem->Key) { + if(akey->ShiftFlags == aelem->ShiftFlags) { + return akey->LineStoreIndex - aelem->LineStoreIndex; + } + return akey->ShiftFlags - aelem->ShiftFlags; + } + return akey->Key - aelem->Key; + } + return(char_key - char_elem); // akey->Key - aelem->Key); +} + +KMX_DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) +{ + PFILE_GROUP gp; + KMX_DWORD msg; + + if (fk->currentGroup == 0xFFFFFFFF) return CERR_None; + // Just got to first group - so nothing to finish yet + + gp = &fk->dpGroupArray[fk->currentGroup]; + + // Finish off the previous group stuff! + if ((msg = ExpandCapsRulesForGroup(fk, gp)) != CERR_None) return msg; + qsort(gp->dpKeyArray, gp->cxKeyArray, sizeof(FILE_KEY), kmcmp::cmpkeys); + + return VerifyUnreachableRules(gp); +} + +/*************************************** +* Store management +*/ + +KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +{ + PKMX_WCHAR q, pp; + PFILE_STORE sp; + //WCHAR temp[GLOBAL_BUFSIZE]; + KMX_DWORD msg; + int i = 0; + + pp = p; + + if ((q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL)) == NULL) return CERR_InvalidStoreLine; + + if (*q == *SSN__PREFIX) + { + for (i = 0; StoreTokens[i]; i++) + if (!u16icmp(q, StoreTokens[i])) // I3481 + break; + if (!StoreTokens[i]) return CERR_InvalidSystemStore; + } + + sp = new FILE_STORE[fk->cxStoreArray + 1]; + if (!sp) return CERR_CannotAllocateMemory; + + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete fk->dpStoreArray; + } + + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; + + sp->line = kmcmp::currentLine; + sp->fIsOption = FALSE; + sp->fIsReserved = FALSE; + sp->fIsStore = FALSE; + sp->fIsDebug = FALSE; + sp->fIsCall = FALSE; + + safe_wcsncpy(sp->szName, q, SZMAX_STORENAME); + { + PKMX_WCHAR temp = new KMX_WCHAR[GLOBAL_BUFSIZE]; + + if ((msg = GetXString(fk, p, u"c\n", temp, GLOBAL_BUFSIZE - 1, (int)(p - pp), &p, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } + + sp->dwSystemID = i; + sp->dpString = new KMX_WCHAR[u16len(temp) + 1]; + u16ncpy(sp->dpString, temp, u16len(temp) + 1); // I3481 + + delete[] temp; + } + + if (xstrlen(sp->dpString) == 1 && *sp->dpString != UC_SENTINEL && + sp->dwSystemID == 0 && (fk->version >= VERSION_60 || fk->version == 0)) + { + // In this case, we want to change behaviour for older versioned keyboards so that + // we don't mix up named character codes which weren't supported in 5.x + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); + // Add a single char store as a defined character constant + if (Uni_IsSurrogate1(*sp->dpString)) + kmcmp::CodeConstants->AddCode(Uni_SurrogateToUTF32(sp->dpString[0], sp->dpString[1]), sp->szName, fk->cxStoreArray); + else + kmcmp::CodeConstants->AddCode(sp->dpString[0], sp->szName, fk->cxStoreArray); + kmcmp::CodeConstants->reindex(); // has to be done after every character add due to possible use in another store. // I4982 + } + + fk->cxStoreArray++; // increment now, because GetXString refers to stores + + if (i > 0) + if ((msg = ProcessSystemStore(fk, i, sp)) != CERR_None) return msg; + + return CheckForDuplicateStore(fk, sp); +} + +KMX_DWORD AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, KMX_WCHAR const * str, KMX_DWORD *dwStoreID) +{ + PFILE_STORE sp; + sp = new FILE_STORE[fk->cxStoreArray + 1]; + if (!sp) return CERR_CannotAllocateMemory; + + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete fk->dpStoreArray; + } + + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; + + sp->line = kmcmp::currentLine; + sp->fIsOption = FALSE; // I3686 + sp->fIsReserved = (SystemID != TSS_NONE); + sp->fIsStore = FALSE; + sp->fIsDebug = FALSE; + sp->fIsCall = FALSE; + + safe_wcsncpy(sp->szName, (PKMX_WCHAR) StoreTokens[SystemID], SZMAX_STORENAME); + + sp->dpString = new KMX_WCHAR[u16len(str) + 1]; + u16ncpy(sp->dpString, str, u16len(str) + 1); // I3481 + + sp->dwSystemID = SystemID; + + if (dwStoreID) *dwStoreID = fk->cxStoreArray; + + fk->cxStoreArray++; + + return ProcessSystemStore( fk, SystemID, sp); +} + +KMX_DWORD AddDebugStore(PFILE_KEYBOARD fk, KMX_WCHAR const * str) +{ + PFILE_STORE sp; + KMX_WCHAR tstr[16]; + u16sprintf(tstr, _countof(tstr), L"%d", kmcmp::currentLine); // I3481 + + sp = new FILE_STORE[fk->cxStoreArray + 1]; + if (!sp) return CERR_CannotAllocateMemory; + + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete[] fk->dpStoreArray; + } + + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; + + safe_wcsncpy(sp->szName, (PKMX_WCHAR) str, SZMAX_STORENAME); + + sp->dpString = new KMX_WCHAR[u16len(tstr) + 1]; + u16ncpy(sp->dpString, tstr, u16len(tstr) + 1); // I3481 + sp->line = 0; + sp->fIsOption = FALSE; + sp->fIsReserved = TRUE; + sp->fIsStore = FALSE; + sp->fIsDebug = TRUE; + sp->fIsCall = FALSE; + sp->dwSystemID = TSS_DEBUG_LINE; + fk->cxStoreArray++; + + return CERR_None; +} + +PKMX_WCHAR pssBuf = NULL; + +KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp) +{ + //WCHAR buf[GLOBAL_BUFSIZE]; + int i, j; + KMX_DWORD msg; + PKMX_WCHAR p, q; + KMX_CHAR *pp; + + if (!pssBuf) pssBuf = new KMX_WCHAR[GLOBAL_BUFSIZE]; + PKMX_WCHAR buf = pssBuf; + + switch (SystemID) + { + case TSS_BITMAP: + if ((msg = ImportBitmapFile(fk, sp->dpString, &fk->dwBitmapSize, &fk->lpBitmap)) != CERR_None) + return msg; + break; + + case TSS_CALLDEFINITION: + break; + + case TSS_CALLDEFINITION_LOADFAILED: + break; + + case TSS_CAPSALWAYSOFF: + if (*sp->dpString == u'1') fk->dwFlags |= KF_CAPSALWAYSOFF; + break; + + case TSS_CAPSONONLY: + if (*sp->dpString == u'1') fk->dwFlags |= KF_CAPSONONLY; + break; + + case TSS_COMPILEDVERSION: + break; + + case TSS_COPYRIGHT: + break; + + case TSS_DEBUG_LINE: + break; + + case TSS_ETHNOLOGUECODE: + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_EthnologueCode); + if ((msg = ProcessEthnologueStore(sp->dpString)) != CERR_None) return msg; // I2646 + break; + + case TSS_HOTKEY: + if ((msg = ProcessHotKey(sp->dpString, &fk->dwHotKey)) != CERR_None) return msg; + u16sprintf(buf, GLOBAL_BUFSIZE, L"%d", (int)fk->dwHotKey); // I3481 + delete[] sp->dpString; + sp->dpString = new KMX_WCHAR[u16len(buf) + 1]; + u16ncpy(sp->dpString, buf, u16len(buf) + 1); // I3481 + break; + + case TSS_INCLUDECODES: + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); + pp = wstrtostr(sp->dpString); + if (!kmcmp::CodeConstants->LoadFile(pp)) + { + delete[] pp; + return CERR_CannotLoadIncludeFile; + } + delete[] pp; + kmcmp::CodeConstants->reindex(); // I4982 + break; + + case TSS_LANGUAGE: + { + KMX_WCHAR *context = NULL; + KMX_WCHAR sep_c[3] = u", "; + PKMX_WCHAR p_sep_c = sep_c; + q = u16tok(sp->dpString, p_sep_c, &context); // I3481 + if (!q) return CERR_InvalidLanguageLine; + + i = xatoi(&q); + KMX_WCHAR sep_n[4] = u" c\n"; + PKMX_WCHAR p_sep_n = sep_n; + q = u16tok(NULL, p_sep_n, &context); // I3481 + if (!q) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_InvalidLanguageLine); + j = SUBLANGID(i); + i = PRIMARYLANGID(i); + } + else + j = xatoi(&q); + + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) return CERR_InvalidLanguageLine; + if (i >= 0x200 || j >= 0x20) AddWarning(CWARN_CustomLanguagesNotSupported); + + fk->KeyboardID = (KMX_DWORD)MAKELANGID(i, j); + + u16sprintf(buf, GLOBAL_BUFSIZE, L"%x %x", i, j); // I3481 + delete[] sp->dpString; + sp->dpString = new KMX_WCHAR[u16len(buf) + 1]; + u16ncpy(sp->dpString, buf, u16len(buf) + 1); // I3481 + + break; + } + case TSS_LANGUAGENAME: + break; + + case TSS_LAYOUT: + if (fk->KeyboardID == 0) return CERR_LayoutButNoLanguage; + + q = sp->dpString; + + fk->KeyboardID |= (xatoi(&q) << 16L); + break; + + case TSS_MESSAGE: + break; + + case TSS_MNEMONIC: + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_MnemonicLayout); + kmcmp::FMnemonicLayout = atoiW(sp->dpString) == 1; + if (kmcmp::FMnemonicLayout && FindSystemStore(fk, TSS_CASEDKEYS) != NULL) { + // The &CasedKeys system store is not supported for + // mnemonic layouts + return CERR_CasedKeysNotSupportedWithMnemonicLayout; + } + break; + + case TSS_NAME: + break; + + case TSS_OLDCHARPOSMATCHING: + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_OldCharPosMatching); + kmcmp::FOldCharPosMatching = atoiW(sp->dpString); + break; + + case TSS_SHIFTFREESCAPS: + if (*sp->dpString == u'1') fk->dwFlags |= KF_SHIFTFREESCAPS; + break; + + case TSS_VERSION: + if ((fk->dwFlags & KF_AUTOMATICVERSION) == 0) return CERR_VersionAlreadyIncluded; + p = sp->dpString; + if (u16tof (p) < 5.0) { + AddWarning(CWARN_OldVersion); + } + + if (u16ncmp(p, u"3.0", 3) == 0) fk->version = VERSION_50; //0x0a0b000n= a.bn + else if (u16ncmp(p, u"3.1", 3) == 0) fk->version = VERSION_50; //all versions < 5.0 + else if (u16ncmp(p, u"3.2", 3) == 0) fk->version = VERSION_50; //we compile as if + else if (u16ncmp(p, u"4.0", 3) == 0) fk->version = VERSION_50; //they are 5.0.100.0 + else if (u16ncmp(p, u"5.01", 4) == 0) fk->version = VERSION_501; + else if (u16ncmp(p, u"5.0", 3) == 0) fk->version = VERSION_50; + else if (u16ncmp(p, u"6.0", 3) == 0) fk->version = VERSION_60; + else if (u16ncmp(p, u"7.0", 3) == 0) fk->version = VERSION_70; + else if (u16ncmp(p, u"8.0", 3) == 0) fk->version = VERSION_80; + else if (u16ncmp(p, u"9.0", 3) == 0) fk->version = VERSION_90; + else if (u16ncmp(p, u"10.0", 4) == 0) fk->version = VERSION_100; + else if (u16ncmp(p, u"14.0", 4) == 0) fk->version = VERSION_140; // Adds support for #917 -- context() with notany() for KeymanWeb + else if (u16ncmp(p, u"15.0", 4) == 0) fk->version = VERSION_150; // Adds support for U_xxxx_yyyy #2858 + + else return CERR_InvalidVersion; + + if (fk->version < VERSION_60) kmcmp::FOldCharPosMatching = TRUE; + + fk->dwFlags &= ~KF_AUTOMATICVERSION; + + break; + + case TSS_VISUALKEYBOARD: + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + { + // Strip path from the store, leaving bare filename only + p = sp->dpString; + + KMX_WCHAR *pp = (KMX_WCHAR*) u16rchr_slash((const PKMX_WCHAR) p); + + if (!pp) { + pp = p; + } else { + pp++; + } + q = new KMX_WCHAR[u16len(pp) + 1]; + u16ncpy(q, pp, u16len(pp) + 1); + + // Change compiled reference file extension to .kvk + pp = ( km_kbp_cp *) u16chr(q, 0) - 5; + if (pp > q && u16icmp(pp, u".kvks") == 0) { + pp[4] = 0; + } + + delete[] sp->dpString; + sp->dpString = q; + + if ((msg = CheckFilenameConsistency( (sp->dpString), FALSE)) != CERR_None) { + return msg; + } + } + break; + case TSS_KMW_RTL: + case TSS_KMW_HELPTEXT: + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + break; + + case TSS_KMW_HELPFILE: + case TSS_KMW_EMBEDJS: + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + if ((msg = CheckFilenameConsistency(sp->dpString, FALSE)) != CERR_None) { + return msg; + } + break; + + case TSS_KMW_EMBEDCSS: + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyEmbedCSS); + if ((msg = CheckFilenameConsistency(sp->dpString, FALSE)) != CERR_None) { + return msg; + } + break; + + case TSS_TARGETS: // I4504 + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyTargets); + break; + + case TSS_WINDOWSLANGUAGES: + { + KMX_WCHAR *context = NULL; + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + size_t szQ = u16len(sp->dpString) * 6 + 1; // I3481 + q = new KMX_WCHAR[szQ]; // guaranteed to be enough space for recoding + *q = 0; KMX_WCHAR *r = q; + KMX_WCHAR sep_s[4] = u" "; + PKMX_WCHAR p_sep_s = sep_s; + p = u16tok(sp->dpString, p_sep_s, &context); // I3481 + while (p) + { + int n = xatoi(&p); + + j = SUBLANGID(n); + i = PRIMARYLANGID(n); + + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) { + delete[] q; + return CERR_InvalidLanguageLine; + } + + u16sprintf(r, szQ - (size_t)(r - q), L"x%04.4x ", n); // I3481 + p = u16tok(NULL, sep_s, &context); // I3481 + r = (KMX_WCHAR*) u16chr(q, 0); // I3481 + } + delete[] sp->dpString; + if (*q) { + *((KMX_WCHAR*) u16chr(q, 0) - 1) = 0; // delete final space - safe because we control the formatting - ugly? scared? + } + sp->dpString = q; + break; + } + case TSS_COMPARISON: + VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + break; + + case TSS_VKDICTIONARY: // I3438 + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyVirtualKeyDictionary); + break; + + case TSS_LAYOUTFILE: // I3483 + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyLayoutFile); // I4140 + if ((msg = CheckFilenameConsistency(sp->dpString, FALSE)) != CERR_None) { + return msg; + } + // Used by KMW compiler + break; + + case TSS_KEYBOARDVERSION: // I4140 + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyKeyboardVersion); + if (!IsValidKeyboardVersion(sp->dpString)) { + return CERR_KeyboardVersionFormatInvalid; + } + break; + + case TSS_CASEDKEYS: + if ((msg = VerifyCasedKeys(sp)) != CERR_None) { + return msg; + } + break; + + case TSS_BEGIN_NEWCONTEXT: + case TSS_BEGIN_POSTKEYSTROKE: + break; + + case TSS_NEWLAYER: + case TSS_OLDLAYER: + break; + + default: + return CERR_InvalidSystemStore; + } + return CERR_None; +} + +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 */ + + do { + if (!iswdigit(*dpString)) { + return FALSE; + } + while (iswdigit(*dpString)) { + dpString++; + } + if (*dpString == '.') { + dpString++; + if (!iswdigit(*dpString)) { + return FALSE; + } + } + } while (*dpString != 0); + + return TRUE; +} + + +KMX_DWORD kmcmp::AddCompilerVersionStore(PFILE_KEYBOARD fk) +{ + KMX_DWORD msg; + + if(!kmcmp::FShouldAddCompilerVersion) { + return CERR_None; + } + + if ((msg = AddStore(fk, TSS_COMPILEDVERSION, KEYMAN_VersionWin_W16)) != CERR_None) return msg; + + return CERR_None; +} + +/**************************** +* Rule lines +*/ + +KMX_DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PKMX_WCHAR context, PKMX_WCHAR output, PKMX_WCHAR key) { + PKMX_WCHAR p, q; + int i; + for (p = output; *p; p = incxstr(p)) { + if (*p == UC_SENTINEL) { + if (*(p + 1) == CODE_INDEX) { + int indexStore = *(p + 2) - 1; + int contextOffset = *(p + 3); + for (q = context, i = 1; *q && i < contextOffset; q = incxstr(q), i++); + + if (*q == 0) { + if (!gp->fUsingKeys) + // no key in the rule, so offset is past end of context + return CERR_IndexDoesNotPointToAny; + if (i < contextOffset) // I4914 + // offset is beyond the key + return CERR_IndexDoesNotPointToAny; + q = key; + } + + // find the any + if (*q != UC_SENTINEL || *(q + 1) != CODE_ANY) + return CERR_IndexDoesNotPointToAny; + + int anyStore = *(q + 2) - 1; + + if (xstrlen(fk->dpStoreArray[indexStore].dpString) < xstrlen(fk->dpStoreArray[anyStore].dpString)) { + AddWarning(CWARN_IndexStoreShort); //TODO: if this fails, then we return FALSE instead of an error + } + } else if (*(p + 1) == CODE_CONTEXTEX) { + int contextOffset = *(p + 2); + if (contextOffset > xstrlen(context)) + return CERR_ContextExHasInvalidOffset; + + // Due to a limitation in earlier versions of KeymanWeb, the minimum version + // for context() referring to notany() is 14.0. See #917 for details. + if (kmcmp::CompileTarget == CKF_KEYMANWEB) { + for (q = context, i = 1; *q && i < contextOffset; q = incxstr(q), i++); + if (*q == UC_SENTINEL && *(q + 1) == CODE_NOTANY) { + VERIFY_KEYBOARD_VERSION(fk, VERSION_140, CERR_140FeatureOnlyContextAndNotAnyWeb); + } + } + } + } + } + return CERR_None; +} + +/** + *Checks that the order of statements in the context matches the specification + * Rule structure: [context] ['+' key] '>' output + * Context structure: [nul] [if()|baselayout()|platform()]+ [char|any|context()|deadkey()|dk()|index()|notany()|outs()] + * Test that nul is first, then if(), baselayout(), platform() statements are before any other content + */ +KMX_BOOL CheckContextStatementPositions(PKMX_WCHAR context) { + KMX_BOOL hadContextChar = FALSE; + for (PKMX_WCHAR p = context; *p; p = incxstr(p)) { + if (*p == UC_SENTINEL) { + switch (*(p + 1)) { + case CODE_NUL: + if (p > context) { + AddWarningBool(CWARN_NulNotFirstStatementInContext); + } + break; + case CODE_IFOPT: + case CODE_IFSYSTEMSTORE: + if (hadContextChar) { + AddWarningBool(CWARN_IfShouldBeAtStartOfContext); + } + break; + default: + hadContextChar = TRUE; + } + } + else { + hadContextChar = TRUE; + } + } + + return TRUE; +} +/** + * Checks if a use() statement is followed by other content in the output of a rule + */ +KMX_DWORD CheckUseStatementsInOutput(const PFILE_GROUP gp,PKMX_WCHAR output) { + KMX_BOOL hasUse = FALSE; + PKMX_WCHAR p; + for (p = output; *p; p = incxstr(p)) { + if (*p == UC_SENTINEL && *(p + 1) == CODE_USE) { + hasUse = TRUE; + } else if (hasUse) { + AddWarning(CWARN_UseNotLastStatementInRule); + break; + } + } + return CERR_None; +} + +/** + * Adds implicit `context` to start of output of rules for readonly groups + */ +KMX_DWORD InjectContextToReadonlyOutput(PKMX_WCHAR pklOut) { + if (pklOut[0] != UC_SENTINEL || pklOut[1] != CODE_CONTEXT) { + if (u16len(pklOut) > GLOBAL_BUFSIZE - 3) { + return CERR_CannotAllocateMemory; + } + memmove(pklOut + 2, pklOut, (u16len(pklOut) + 1) * 2); + pklOut[0] = UC_SENTINEL; + pklOut[1] = CODE_CONTEXT; + } + return CERR_None; +} + +/** + * Verifies that a keyboard does not attempt to emit characters or + * other changes to text store when processing a readonly group + */ +KMX_DWORD CheckOutputIsReadonly(const PFILE_KEYBOARD fk, const PKMX_WCHAR output) { // I4867 + PKMX_WCHAR p; + for (p = output; *p; p = incxstr(p)) { + if (*p != UC_SENTINEL) { + return CERR_OutputInReadonlyGroup; + } + switch (*(p + 1)) { + case CODE_CALL: + // We cannot be sure that the callee is going to be readonly + // but we have to operate on a trust basis for call() in any + // case, so we'll allow it. + continue; + case CODE_USE: + // We only allow use() of other readonly groups + { + PFILE_GROUP targetGroup = &fk->dpGroupArray[*(p + 2) - 1]; + if (!targetGroup->fReadOnly) { + return CERR_CannotUseReadWriteGroupFromReadonlyGroup; + } + } + continue; + case CODE_SETOPT: + case CODE_RESETOPT: + case CODE_SAVEOPT: + // it is okay to set, reset or save keyboard options + // although it's hard to see good use cases for this + continue; + case CODE_SETSYSTEMSTORE: + // it is okay to set system stores; Engine or Core will + // ignore set(&) that are not permissible in the given context + continue; + case CODE_CONTEXT: + // We allow `context` but only as the very first statement in output + if (p == output) { + continue; + } + return CERR_OutputInReadonlyGroup; + default: + // Note: conceptually, CODE_NUL could be transformed to CODE_CONTEXT + // if the context was also empty, but it is probably safest to avoid this, + // given CODE_CONTEXT does what we need anyway + return CERR_StatementNotPermittedInReadonlyGroup; + } + } + return CERR_None; +} + +KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode, PKMX_WCHAR pklIn, PKMX_WCHAR pklKey, PKMX_WCHAR pklOut); + +KMX_DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode) +{ + PKMX_WCHAR pklIn, pklKey, pklOut; + + pklIn = new KMX_WCHAR[GLOBAL_BUFSIZE]; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer + pklKey = new KMX_WCHAR[GLOBAL_BUFSIZE]; + pklOut = new KMX_WCHAR[GLOBAL_BUFSIZE]; + if (!pklIn || !pklKey || !pklOut) + return CERR_CannotAllocateMemory; // forget about the little leak if pklKey or pklOut fail... + + KMX_DWORD result = ProcessKeyLineImpl(fk, str, IsUnicode, pklIn, pklKey, pklOut); + + delete[] pklIn; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer + delete[] pklKey; + delete[] pklOut; + + return result; +} + +KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode, PKMX_WCHAR pklIn, PKMX_WCHAR pklKey, PKMX_WCHAR pklOut) { + PKMX_WCHAR p, pp; + KMX_DWORD msg; + PFILE_GROUP gp; + PFILE_KEY kp; + + gp = &fk->dpGroupArray[fk->currentGroup]; + + pp = str; + + if (gp->fUsingKeys) { + if ((msg = GetXString(fk, str, u"+", pklIn, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + + str = p + 1; + if ((msg = GetXString(fk, str, u">", pklKey, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if (pklKey[0] == 0) return CERR_ZeroLengthString; + if (xstrlen(pklKey) > 1) AddWarning(CWARN_KeyBadLength); + } else { + if ((msg = GetXString(fk, str, u">", pklIn, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if (pklIn[0] == 0) return CERR_ZeroLengthString; + } + + str = p + 1; + if ((msg = GetXString(fk, str, u"c\n", pklOut, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + + if (pklOut[0] == 0) return CERR_ZeroLengthString; + + CheckContextStatementPositions(pklIn); + + // Test index and context offsets in context + if ((msg = CheckStatementOffsets(fk, gp, pklIn, pklOut, pklKey)) != CERR_None) return msg; + + // Test that use() statements are not followed by other content + if ((msg = CheckUseStatementsInOutput(gp, pklOut)) != CERR_None) { + return msg; // I4867 + } + + if (gp->fReadOnly) { + // Ensure no output is made from the rule, and that + // use() statements meet required readonly semantics + if ((msg = CheckOutputIsReadonly(fk, pklOut)) != CERR_None) { + return msg; + } + + // Inject `context` to start of output if group is readonly + // to keep the output internally consistent + if ((msg = InjectContextToReadonlyOutput(pklOut)) != CERR_None) { + return msg; + } + } + + kp = new FILE_KEY[gp->cxKeyArray + 1]; + if (!kp) return CERR_CannotAllocateMemory; + if (gp->dpKeyArray) + { + memcpy(kp, gp->dpKeyArray, gp->cxKeyArray * sizeof(FILE_KEY)); + delete gp->dpKeyArray; + } + + gp->dpKeyArray = kp; + kp = &gp->dpKeyArray[gp->cxKeyArray]; + + gp->cxKeyArray++; + + kp->dpOutput = new KMX_WCHAR[u16len(pklOut) + 1]; + u16ncpy(kp->dpOutput, pklOut, u16len(pklOut) + 1); // I3481 + + kp->dpContext = new KMX_WCHAR[u16len(pklIn) + 1]; + u16ncpy(kp->dpContext, pklIn, u16len(pklIn) + 1); // I3481 + + kp->Line = kmcmp::currentLine; + kp->LineStoreIndex = 0; + + // Finished if we are not using keys + + if (!gp->fUsingKeys) + { + kp->Key = 0; + kp->ShiftFlags = 0; + return CERR_None; + } + + // Expand each rule out into multiple rules - much faster processing at the key hit time + + if (*pklKey == 0) return CERR_ZeroLengthString; + + if (*pklKey == UC_SENTINEL) + switch (*(pklKey + 1)) + { + case CODE_ANY: + kp->ShiftFlags = 0; + if ((msg = ExpandKp(fk, kp, *(pklKey + 2) - 1)) != CERR_None) return msg; + break; + + case CODE_EXTENDED: + kp->Key = *(pklKey + 3); + kp->ShiftFlags = *(pklKey + 2); + break; + + default: + return CERR_InvalidCodeInKeyPartOfRule; + } + else + { + kp->ShiftFlags = 0; + kp->Key = *pklKey; + } + + return CERR_None; +} + + + +KMX_DWORD ExpandKp_ReplaceIndex(PFILE_KEYBOARD fk, PFILE_KEY k, KMX_DWORD keyIndex, int nAnyIndex) +{ + /* Replace each index(xx,keyIndex) in k->dpOutput with appropriate char as based on nAnyIndex */ + PFILE_STORE s; + int i; + PKMX_WCHAR pIndex, pStore; + + for (pIndex = k->dpOutput; *pIndex; pIndex = incxstr(pIndex)) + { + if (*pIndex == UC_SENTINEL && *(pIndex + 1) == CODE_INDEX && *(pIndex + 3) == keyIndex) + { + s = &fk->dpStoreArray[*(pIndex + 2) - 1]; + for (i = 0, pStore = s->dpString; i < nAnyIndex; i++, pStore = incxstr(pStore)); + PKMX_WCHAR qStore = incxstr(pStore); + + int w = (int)(qStore - pStore); + if (w > 4) + { + *pIndex = UC_SENTINEL; + *(pIndex + 1) = CODE_BEEP; + memmove(pIndex + 2, pIndex + 4, u16len(pIndex + 3) * 2); + } + else + { + memcpy(pIndex, pStore, w * 2); + if (w < 4) memmove(pIndex + w, pIndex + 4, u16len(pIndex + 3) * 2); + } + } + } + + return CERR_None; +} + + +KMX_DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, KMX_DWORD storeIndex) +{ + PFILE_KEY k; + PKMX_WCHAR pn; + KMX_DWORD nchrs, n; + int keyIndex; + + PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; + PFILE_GROUP gp = &fk->dpGroupArray[fk->currentGroup]; + + PKMX_WCHAR dpContext = kpp->dpContext; + PKMX_WCHAR dpOutput = kpp->dpOutput; + + nchrs = xstrlen(sp->dpString); + pn = sp->dpString; + keyIndex = xstrlen(dpContext) + 1; + + /* + Now we change them to plain characters in the output in multiple rules, + and set the keystroke to the appropriate character in the store. + */ + + k = new FILE_KEY[gp->cxKeyArray + nchrs - 1]; + if (!k) return CERR_CannotAllocateMemory; + memcpy(k, gp->dpKeyArray, gp->cxKeyArray * sizeof(FILE_KEY)); + + kpp = &k[(int)(kpp - gp->dpKeyArray)]; + + delete gp->dpKeyArray; + gp->dpKeyArray = k; + gp->cxKeyArray += nchrs - 1; + + for (k = kpp, n = 0, pn = sp->dpString; *pn; pn = incxstr(pn), k++, n++) + { + k->dpContext = new KMX_WCHAR[u16len(dpContext) + 1]; + k->dpOutput = new KMX_WCHAR[u16len(dpOutput) + 1]; + + u16ncpy(k->dpContext, dpContext, u16len(dpContext) + 1); // copy the context. // I3481 + u16ncpy(k->dpOutput, dpOutput, u16len(dpOutput) + 1); // copy the output. + + if (*pn == UC_SENTINEL) + { + switch (*(pn + 1)) + { + case CODE_EXTENDED: + k->Key = *(pn + 3); // set the key to store offset. + k->ShiftFlags = *(pn + 2); + break; + default: + return CERR_CodeInvalidInKeyStore; + } + } + else + { + k->Key = *pn; // set the key to store offset. + k->ShiftFlags = 0; + } + k->Line = kpp->Line; + k->LineStoreIndex = n; + ExpandKp_ReplaceIndex(fk, k, keyIndex, n); + } + + delete dpContext; + delete dpOutput; + + return CERR_None; +} + + +PKMX_WCHAR GetDelimitedString(PKMX_WCHAR *p, KMX_WCHAR const * Delimiters, KMX_WORD Flags) +{ + PKMX_WCHAR q, r; + KMX_WCHAR dOpen, dClose; + + dOpen = *Delimiters; dClose = *(Delimiters + 1); + + q = *p; + while (iswspace(*q)) q++; //***QUERY + + if (*q != dOpen) return NULL; + + q++; + + r = xstrchr(q, &dClose); // Find closing delimiter + if (!r) return NULL; + + if (Flags & GDS_CUTLEAD) + while (iswspace(*q)) q++; // cut off leading spaces + + if (Flags & GDS_CUTFOLL) + if (!iswspace(*(r - 1))) *r = 0; + else + { + r--; // Cut off following spaces + while (iswspace(*r) && r > q) r--; + r++; + *r = 0; r = xstrchr((r + 1), &dClose); + } + else *r = 0; + + r++; while (iswspace(*r)) r++; // Ignore spaces after the close + if (*r == 0) r--; // Safety for terminating strings. + + *p = r; // Update pointer position + + return q; // Return delimited string +} + +#ifndef __iswcsym +#define __iswcsym(_c) (iswalnum(_c) || ((_c)=='_')) +#endif + +LinePrefixType GetLinePrefixType(PKMX_WCHAR *p) +{ + PKMX_WCHAR s = *p; + + while (iswspace(*s)) s++; + + PKMX_WCHAR q = s; + + if (*s != '$') return lptNone; + + /* I1569 - fix named constants at the start of the line */ + s++; + while (__iswcsym(*s)) s++; + if (*s != ':') return lptNone; + + if (u16nicmp(q, u"$keyman:", 8) == 0) + { + *p += 8; + return lptKeymanAndKeymanWeb; + } + if (u16nicmp(q, u"$keymanweb:", 11) == 0) + { + *p += 11; + return lptKeymanWebOnly; + } + if (u16nicmp(q, u"$keymanonly:", 12) == 0) + { + *p += 12; + return lptKeymanOnly; + } + + return lptOther; +} + +int LineTokenType(PKMX_WCHAR *str) +{ + int i; + size_t l; + PKMX_WCHAR p = *str; + + LinePrefixType lpt = GetLinePrefixType(&p); + if (lpt == lptOther) return T_BLANK; + + /* Test KeymanWeb, Keyman and KeymanOnly prefixes */ + if (kmcmp::CompileTarget == CKF_KEYMAN && lpt == lptKeymanWebOnly) return T_BLANK; + if (kmcmp::CompileTarget == CKF_KEYMANWEB && lpt == lptKeymanOnly) return T_BLANK; + + while (iswspace(*p)) p++; + + if (u16chr(LineTokens[0], towupper(*p))) + for (i = 0; i <= T_W_END - T_W_START; i++) + { + l = u16len(LineTokens[i + 1]); + if (u16nicmp(p, LineTokens[i + 1], l) == 0) + { + p += l; while (iswspace(*p)) p++; *str = p; + return i + T_W_START; + } + } + + switch (towupper(*p)) + { + case 'C': + if (iswspace(*(p + 1))) return T_COMMENT; + break; + case 0: + return T_BLANK; + default: + if (u16chr(u"\"aAbBlLpPnN[OoxXdD0123456789\'+UuiI$", *p)) // I4784 + { + *str = p; + return T_KEYTOKEY; + } + } + return T_UNKNOWN; +} + +KMX_WCHAR const * DeadKeyChars = +u"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + +KMX_BOOL StrValidChrs(PKMX_WCHAR q, KMX_WCHAR const * chrs) +{ + for (; *q; q++) + if (!u16chr(chrs, *q)) return FALSE; + return TRUE; +} + +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 isVKey, int isUnicode +); + +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 +) { + PKMX_WCHAR tstr = new KMX_WCHAR[max]; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer - GetXString is re-entrant with if() + KMX_DWORD err = GetXStringImpl(tstr, fk, str, token, output, max, offset, newp, isVKey, isUnicode); + delete[] tstr; + return err; +} + +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 isVKey, int isUnicode +) { + KMX_DWORD err; + PKMX_WCHAR p = str, q, r; + int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, sFlag = 0, j; + KMX_DWORD i; + KMX_BOOL finished = FALSE; + KMX_WCHAR c; + + *tstr = 0; + + *output = 0; + + p = str; + do + { + tokenFound = FALSE; + while (iswspace(*p) && !u16chr(token, *p)) p++; + if (!*p) break; + + ErrChr = (int)(p - str) + offset + 1; + + /* + char *tokenTypes[] = { + "clearcontext", "deadkey", "context", "return", "switch", + "index", "outs", "beep", "nul", "use", "any", "fix", "dk", "k_", "x", "d", "c", + "[", "]" }; + */ + + switch (towupper(*p)) + { + case 'X': + case 'D': type = 0; break; // xFF, d130: chars, deadkey(n) + case '\"': type = 1; break; // "xxxx": chars + case '\'': type = 2; break; // 'xxxx': chars + case 'A': type = 3; break; // any(s) + case 'B': type = 4; break; // beep, baselayout (synonym for if(&baselayout)) // I3430 + case 'I': type = 5; break; // index(s,n), if + case 'O': type = 6; break; // outs(s) + case 'C': type = 7; break; // context, comments, clearcontext, call(s) + case 'N': type = 8; break; // nul, notany + case 'U': type = 9; break; // use(g) + case 'R': type = 10; break; // return, reset + case '[': type = 11; break; // start of vkey section + //case ']': type = 12; break; // end of vkey section + //case 'K': type = 13; break; // virtual key name or "key" + case 'S': type = 14; break; // switch, set, save + case 'F': type = 15; break; // fix (synonym for clearcontext) + case '$': type = 16; break; // named code constants + case 'P': type = 17; break; // platform (synonym for if(&platform)) // I3430 + case 'L': type = 18; break; // layer (synonym for set(&layer)) // I3437 + case '.': type = 19; break; // .. allows us to specify ranges -- either vkeys or characters + default: + if (iswdigit(*p)) type = 0; // octal number + else type = 99; // error! + } + if (u16chr(token, *p)) tokenFound = TRUE; + + switch (type) + { + case 99: + if (tokenFound) break; + { + sprintf(ErrExtraLIB,"token: %c",(int)*p); + } + return CERR_InvalidToken; + case 0: + if (u16nicmp(p, u"deadkey", z = 7) == 0 || + u16nicmp(p, u"dk", z = 2) == 0) + { + p += z; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidDeadkey; + + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_DEADKEY; + if (!StrValidChrs(q, DeadKeyChars)) return CERR_InvalidDeadkey; + tstr[mx++] = GetDeadKey(fk, q); //atoiW(q); 7-5-01: named deadkeys + tstr[mx] = 0; + } + else + { + n = xatoi(&p); + if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; + if ((err = kmcmp::UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; + tstr[mx++] = n1; + if (n2 >= 0) tstr[mx++] = n2; + tstr[mx] = 0; + } + continue; + + case 1: + q = (PKMX_WCHAR) u16chr(p + 1, '\"'); + if (!q) return CERR_UnterminatedString; + if ((int)(q - p) - 1 + mx > max) return CERR_UnterminatedString; + if (sFlag) return CERR_StringInVirtualKeySection; + u16ncat(tstr, p + 1, (int)(q - p) - 1); // I3481 + mx += (int)(q - p) - 1; + tstr[mx] = 0; + p = q + 1; + continue; + case 2: + q = (PKMX_WCHAR) u16chr(p + 1, '\''); + if (!q) return CERR_UnterminatedString; + if ((int)(q - p) - 1 + mx > max) return CERR_UnterminatedString; + if (sFlag) return CERR_StringInVirtualKeySection; + u16ncat(tstr, p + 1, (int)(q - p) - 1); // I3481 + mx += (int)(q - p) - 1; + tstr[mx] = 0; + p = q + 1; + continue; + case 3: + if (u16nicmp(p, u"any", 3) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_AnyInVirtualKeySection; + p += 3; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidAny; + + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + + if (!*fk->dpStoreArray[i].dpString) return CERR_ZeroLengthString; + kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); + + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_ANY; + tstr[mx++] = (KMX_WCHAR)i + 1; // store to index + 1, avoids End-of-string + tstr[mx] = 0; + continue; + case 4: + if (u16nicmp(p, u"beep", 4) == 0) + { + if (sFlag) return CERR_BeepInVirtualKeySection; + p += 4; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_BEEP; + tstr[mx] = 0; + } + else if (u16nicmp(p, u"baselayout", 10) == 0) // I3430 + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 10; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidToken; + err = process_baselayout(fk, q, tstr, &mx); + if (err != CERR_None) return err; + } + else + return CERR_InvalidToken; + + continue; + case 5: + if (u16nicmp(p, u"if", 2) == 0) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 2; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidIf; + + err = process_if(fk, q, tstr, &mx); + if (err != CERR_None) return err; + } + else + { + if (u16nicmp(p, u"index", 5) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_IndexInVirtualKeySection; + p += 5; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + + if (!q || !*q) return CERR_InvalidIndex; + + { + KMX_WCHAR *context = NULL; + KMX_WCHAR sep_com[3] = u" ,"; + PKMX_WCHAR p_sep_com = sep_com; + r = u16tok(q, p_sep_com, &context); // I3481 + if (!r) return CERR_InvalidIndex; + + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(r, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + + kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); + + r = u16tok(NULL, p_sep_com, &context); // I3481 + if (!r) return CERR_InvalidIndex; + } + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_INDEX; + tstr[mx++] = (KMX_WCHAR)i + 1; // avoid EOS for stores + tstr[mx++] = atoiW(r); // character offset of original any. + + tstr[mx] = 0; + } + continue; + case 6: + if (u16nicmp(p, u"outs", 4) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_OutsInVirtualKeySection; + p += 4; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidOuts; + + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + + kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); + + for (q = fk->dpStoreArray[i].dpString; *q; q++) + { + tstr[mx++] = *q; + if (mx >= max - 1) return CERR_BufferOverflow; + } + tstr[mx] = 0; + continue; + case 7: + if (iswspace(*(p + 1))) break; // is a comment -- pre-stripped - so why this test? + if (u16nicmp(p, u"context", 7) == 0) + { + if (sFlag) return CERR_ContextInVirtualKeySection; + p += 7; + + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (q && *q) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_Contextn); + int n1; + n1 = atoiW(q); + if (n1 < 1 || n1 >= 0xF000) return CERR_InvalidToken; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CONTEXTEX; + tstr[mx++] = n1; + tstr[mx] = 0; + } + else + { + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CONTEXT; + tstr[mx] = 0; + } + } + else if (u16nicmp(p, u"clearcontext", 12) == 0) + { + p += 12; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CLEARCONTEXT; + tstr[mx] = 0; + } + else if (u16nicmp(p, u"call", 4) == 0) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_501, CERR_501FeatureOnly_Call); + if (sFlag) return CERR_CallInVirtualKeySection; + p += 4; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidCall; + + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + + if (!kmcmp::IsValidCallStore(&fk->dpStoreArray[i])) return CERR_InvalidCall; + kmcmp::CheckStoreUsage(fk, i, FALSE, FALSE, TRUE); + + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CALL; + tstr[mx++] = (KMX_WCHAR)i + 1; + tstr[mx] = 0; + + fk->dpStoreArray[i].dwSystemID = TSS_CALLDEFINITION; + } + else + return CERR_InvalidToken; + continue; + case 8: + if (u16nicmp(p, u"notany", 6) == 0) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly) + if (sFlag) return CERR_AnyInVirtualKeySection; + p += 6; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidAny; + + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_NOTANY; + tstr[mx++] = (KMX_WCHAR)i + 1; // store to index + 1, avoids End-of-string + tstr[mx] = 0; + continue; + } + if (u16nicmp(p, u"nul", 3) != 0) return CERR_InvalidToken; + + p += 3; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_NUL; + tstr[mx] = 0; + continue; + case 9: + if (u16nicmp(p, u"use", 3) != 0) + { + if (*(p + 1) == '+') + { + n = xatoi(&p); + if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; + if ((err = kmcmp::UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; + tstr[mx++] = n1; + if (n2 >= 0) tstr[mx++] = n2; + tstr[mx] = 0; + if (!isUnicode) AddWarning(CWARN_UnicodeInANSIGroup); + continue; + } + return CERR_InvalidToken; + } + p += 3; + + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidUse; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_USE; + tstr[mx] = GetGroupNum(fk, q); + if (tstr[mx] == 0) return CERR_GroupDoesNotExist; + tstr[++mx] = 0; + continue; + case 10: + if (u16nicmp(p, u"reset", 5) == 0) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 5; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidReset; + + err = process_reset(fk, q, tstr, &mx); + if (err != CERR_None) return err; + } + else + { + if (u16nicmp(p, u"return", 6) != 0) return CERR_InvalidToken; + + p += 6; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_RETURN; + tstr[mx] = 0; + u16ncpy(output, tstr, max); // I3481 + output[max - 1] = 0; + return 0; + } + continue; + case 11: + p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; + + //printf("--EXTENDEDSTRING--\n"); + + do + { + while (iswspace(*p)) p++; + + switch (towupper(*p)) + { + case 'N': + if (u16nicmp(p, u"NCAPS", 5) == 0) + sFlag |= NOTCAPITALFLAG, p += 5; + else finished = TRUE; + break; + case 'L': + if (u16nicmp(p, u"LALT", 4) == 0) + sFlag |= LALTFLAG, p += 4; + else if (u16nicmp(p, u"LCTRL", 5) == 0) + sFlag |= LCTRLFLAG, p += 5; + else finished = TRUE; + break; + case 'R': + if (u16nicmp(p, u"RALT", 4) == 0) + sFlag |= RALTFLAG, p += 4; + else if (u16nicmp(p, u"RCTRL", 5) == 0) + sFlag |= RCTRLFLAG, p += 5; + else finished = TRUE; + break; + case 'A': + if (u16nicmp(p, u"ALT", 3) == 0) + sFlag |= K_ALTFLAG, p += 3; + else finished = TRUE; + break; + case 'C': + if (u16nicmp(p, u"CTRL", 4) == 0) + sFlag |= K_CTRLFLAG, p += 4; + else if (u16nicmp(p, u"CAPS", 4) == 0) + sFlag |= CAPITALFLAG, p += 4; + else finished = TRUE; + break; + case 'S': + if (u16nicmp(p, u"SHIFT", 5) == 0) + sFlag |= K_SHIFTFLAG, p += 5; + else finished = TRUE; + break; + default: + finished = TRUE; + break; + } + } while (!finished); + + if ((sFlag & (LCTRLFLAG | LALTFLAG)) && (sFlag & (RCTRLFLAG | RALTFLAG))) { + AddWarning(CWARN_MixingLeftAndRightModifiers); + } + + // If we use chiral modifiers, or we use state keys, and we target web in the keyboard, and we don't manually specify a keyboard version, bump the minimum + // version to 10.0. This makes an assumption that if we are using these features in a keyboard and it has no version specified, that we want to use the features + // in the web target platform, even if there are platform() rules excluding this possibility. In that (rare) situation, the keyboard developer should simply specify + // the &version to be 9.0 or whatever to avoid this behaviour. + if (sFlag & (LCTRLFLAG | LALTFLAG | RCTRLFLAG | RALTFLAG | CAPITALFLAG | NOTCAPITALFLAG | NUMLOCKFLAG | NOTNUMLOCKFLAG | SCROLLFLAG | NOTSCROLLFLAG) && + kmcmp::CompileTarget == CKF_KEYMANWEB && + fk->dwFlags & KF_AUTOMATICVERSION) { + VERIFY_KEYBOARD_VERSION(fk, VERSION_100, 0); + } + //printf("sFlag: %x\n", sFlag); + + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_EXTENDED; + tstr[mx++] = sFlag; + + while (iswspace(*p)) p++; + + q = p; + + if (*q == ']') + { + return CERR_InvalidToken; // I3137 - key portion of VK is missing e.g. "[CTRL ALT]", this generates invalid kmx file that can crash Keyman or compiler later on // I3511 + } + + while (*q != ']') + { + if (*q == '\'' || *q == '"') + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_VirtualCharKey); + if (!kmcmp::FMnemonicLayout) AddWarning(CWARN_VirtualCharKeyWithPositionalLayout); + KMX_WCHAR chQuote = *q; + q++; if (*q == chQuote || *q == '\n' || *q == 0) return CERR_InvalidToken; + tstr[mx - 1] |= VIRTUALCHARKEY; + tstr[mx++] = *q; + q++; if (*q != chQuote) return CERR_InvalidToken; + q++; + while (iswspace(*q)) q++; + if (*q != ']') return CERR_InvalidToken; + break; /* out of while loop */ + } + + for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); + + if (*q == 0) return CERR_InvalidToken; + + KMX_WCHAR vkname[SZMAX_VKDICTIONARYNAME]; // I3438 + + if (j >= SZMAX_VKDICTIONARYNAME) return CERR_InvalidToken; + + u16ncpy(vkname, p, j); // I3481 + vkname[j] = 0; + + if (u16icmp(vkname, u"K_NPENTER") == 0) + i = 5; // I649 - K_NPENTER hack + else + { + for (i = 0; i <= VK__MAX; i++) + { + if (u16icmp(vkname, VKeyNames[i]) == 0 || u16icmp(vkname, VKeyISO9995Names[i]) == 0) + break; + } + } + + if (i == VK__MAX + 1) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_InvalidToken); + + i = GetVKCode(fk, vkname); // I3438 + if (i == 0) + return CERR_InvalidToken; + } + + p = q; + + tstr[mx++] = (int)i; + + if (kmcmp::FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) AddWarning(CWARN_VirtualKeyWithMnemonicLayout); // I3438 + + while (iswspace(*q)) q++; + } + tstr[mx++] = UC_SENTINEL_EXTENDEDEND; + tstr[mx] = 0; + //printf("--EXTENDEDEND--\n"); + + p = q + 1; + + sFlag = 0; + + continue; + case 14: + if (u16nicmp(p, u"set", 3) == 0) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + p += 3; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidSet; + + err = process_set(fk, q, tstr, &mx); + if (err != CERR_None) return err; + } + else if (u16nicmp(p, u"save", 4) == 0) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + p += 4; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidSave; + + err = process_save(fk, q, tstr, &mx); + if (err != CERR_None) return err; + } + else + { + if (u16nicmp(p, u"switch", 6) != 0) return CERR_InvalidToken; + p += 6; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidSwitch; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_SWITCH; + tstr[mx++] = atoiW(q); + tstr[mx] = 0; + } + continue; + case 15: + if (u16nicmp(p, u"fix", 3) == 0) + { + p += 3; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CLEARCONTEXT; + tstr[mx] = 0; + } + else + return CERR_InvalidToken; + continue; + case 16: + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); + q = p + 1; + while (*q && !iswspace(*q)) q++; + c = *q; *q = 0; + n = kmcmp::CodeConstants->GetCode(p + 1, &i); + *q = c; + if (n == 0) return CERR_InvalidNamedCode; + if (i < 0xFFFFFFFFL) kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); // I2993 + if (n > 0xFFFF) + { + tstr[mx++] = Uni_UTF32ToSurrogate1(n); + tstr[mx++] = Uni_UTF32ToSurrogate2(n); + } + else + tstr[mx++] = n; + tstr[mx] = 0; + p = q; + continue; + case 17: + if (u16nicmp(p, u"platform", 8) != 0) return CERR_InvalidToken; // I3430 + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 8; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidToken; + err = process_platform(fk, q, tstr, &mx); + if (err != CERR_None) return err; + continue; + case 18: // I3437 + if (u16nicmp(p, u"layer", 5) != 0) return CERR_InvalidToken; + VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_SetSystemStores); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 5; + q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidToken; + err = process_set_synonym(TSS_LAYER, fk, q, tstr, &mx); + if (err != CERR_None) return err; + continue; + case 19: // #2241 + if (*(p + 1) != '.') return CERR_InvalidToken; + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 2; + err = process_expansion(fk, p, tstr, &mx, max); + if (err != CERR_None) return err; + continue; + default: + return CERR_InvalidToken; + } + if (tokenFound) + { + *newp = p; + u16ncpy(output, tstr, max); // I3481 + output[max - 1] = 0; + ErrChr = 0; + return CERR_None; + } + if (mx >= max) return CERR_BufferOverflow; + } while (*p); + + if (!*token) + { + *newp = p; + u16ncpy(output, tstr, max); // I3481 + output[max - 1] = 0; + ErrChr = 0; + return CERR_None; + } + + return CERR_NoTokensFound; +} + +KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx); // I3430 + +KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // I3430 +{ + /* baselayout() */ + return process_if_synonym(TSS_BASELAYOUT, fk, q, tstr, mx); +} + +KMX_DWORD process_platform(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // I3430 +{ + /* platform() */ + return process_if_synonym(TSS_PLATFORM, fk, q, tstr, mx); +} + +KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // I3430 +{ + PKMX_WCHAR temp = new KMX_WCHAR[GLOBAL_BUFSIZE]; + + KMX_DWORD msg; + + PKMX_WCHAR r; + + if ((msg = GetXString(fk, q, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } + + KMX_DWORD dwStoreID; + + if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) + { + delete[] temp; + return msg; + } + + tstr[(*mx)++] = UC_SENTINEL; + tstr[(*mx)++] = (KMX_WCHAR)CODE_IFSYSTEMSTORE; + tstr[(*mx)++] = (KMX_WCHAR)(dwSystemID + 1); // I4785 + tstr[(*mx)++] = 2; + tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); + tstr[(*mx)] = 0; + + delete[] temp; + + return CERR_None; +} + +KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // I3431 +{ + /* if( <'='|'!='> ) */ + KMX_DWORD i, code; + KMX_DWORD nnot = FALSE; + PKMX_WCHAR r = q, s = q; + while (*s && *s != u' ' && *s != u'!' && *s !=u'=') s++; + r = s; + while (*s == u' ') s++; + if (*s == u'!') + { + s++; + nnot = TRUE; + } + + if (*s != '=') return CERR_InvalidIf; + s++; + while (*s == ' ') s++; + *r = 0; + r = q; + + if (r[0] == '&') + { + VERIFY_KEYBOARD_VERSION( fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); + for (i = 0; StoreTokens[i]; i++) + { + if (u16icmp(r, StoreTokens[i]) == 0) break; + } + if (!StoreTokens[i]) return CERR_IfSystemStore_NotFound; + code = CODE_IFSYSTEMSTORE; + } + else + { + code = CODE_IFOPT; + + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(r, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); + } + + PKMX_WCHAR temp = new KMX_WCHAR[GLOBAL_BUFSIZE]; + + KMX_DWORD msg; + + if ((msg = GetXString(fk, s, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } + + KMX_DWORD dwStoreID; + + if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) + { + delete[] temp; + return msg; + } + + tstr[(*mx)++] = UC_SENTINEL; + tstr[(*mx)++] = (KMX_WCHAR)code; + tstr[(*mx)++] = (KMX_WCHAR)(i + 1); + tstr[(*mx)++] = nnot ? 1 : 2; + tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); + tstr[(*mx)] = 0; + + return CERR_None; +} + +KMX_DWORD process_reset(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +{ + /* reset() */ + KMX_DWORD i; + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); + + tstr[(*mx)++] = UC_SENTINEL; + tstr[(*mx)++] = CODE_RESETOPT; + tstr[(*mx)++] = (KMX_WCHAR)(i + 1); + tstr[(*mx)] = 0; + + return CERR_None; +} + +KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx, int max) { + KMX_BOOL isVKey = FALSE; + + KMX_WORD BaseKey=0, BaseShiftFlags=0; + KMX_DWORD BaseChar=0; + + if (*mx == 0) { + return CERR_ExpansionMustFollowCharacterOrVKey; + } + PKMX_WCHAR p = &tstr[*mx]; + p = decxstr(p, tstr); + if (*p == UC_SENTINEL) { + if (*(p + 1) != CODE_EXTENDED) { + return CERR_ExpansionMustFollowCharacterOrVKey; + } + isVKey = TRUE; + BaseKey = *(p + 3); + BaseShiftFlags = *(p + 2); + } + else { + BaseChar = Uni_UTF16ToUTF32(p); + } + + // Look ahead at next element + KMX_WCHAR temp[GLOBAL_BUFSIZE]; + PKMX_WCHAR r = NULL; + + KMX_DWORD msg; + + if ((msg = GetXString(fk, q, u"", temp, _countof(temp) - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + return msg; + } + + KMX_WORD HighKey, HighShiftFlags; + KMX_DWORD HighChar; + + switch(temp[0]) { + case 0: + return isVKey ? CERR_VKeyExpansionMustBeFollowedByVKey : CERR_CharacterExpansionMustBeFollowedByCharacter; + case UC_SENTINEL: + // Verify that range is valid virtual key range + if(!isVKey) { + return CERR_CharacterExpansionMustBeFollowedByCharacter; + } + if (temp[1] != CODE_EXTENDED) { + return CERR_VKeyExpansionMustBeFollowedByVKey; + } + HighKey = temp[3], HighShiftFlags = temp[2]; + if (HighShiftFlags != BaseShiftFlags) { + return CERR_VKeyExpansionMustUseConsistentShift; + } + if (HighKey <= BaseKey) { + return CERR_ExpansionMustBePositive; + } + // Verify space in buffer + if (*mx + (HighKey - BaseKey) * 5 + 1 >= max) return CERR_BufferOverflow; + // Inject an expansion. + for (BaseKey++; BaseKey < HighKey; BaseKey++) { + // < HighKey because caller will add HighKey to output + tstr[(*mx)++] = UC_SENTINEL; + tstr[(*mx)++] = CODE_EXTENDED; + tstr[(*mx)++] = BaseShiftFlags; + tstr[(*mx)++] = BaseKey; + tstr[(*mx)++] = UC_SENTINEL_EXTENDEDEND; + } + tstr[*mx] = 0; + break; + default: + // Verify that range is a valid character range + if (isVKey) { + return CERR_VKeyExpansionMustBeFollowedByVKey; + } + + HighChar = Uni_UTF16ToUTF32(temp); + if (HighChar <= BaseChar) { + return CERR_ExpansionMustBePositive; + } + // Inject an expansion. + for (BaseChar++; BaseChar < HighChar; BaseChar++) { + // < HighChar because caller will add HighChar to output + if (Uni_IsSMP(BaseChar)) { + // We'll test on each char to avoid complex calculations crossing SMP boundary + if (*mx + 3 >= max) return CERR_BufferOverflow; + tstr[(*mx)++] = (KMX_WCHAR) Uni_UTF32ToSurrogate1(BaseChar); + tstr[(*mx)++] = (KMX_WCHAR) Uni_UTF32ToSurrogate2(BaseChar); + } + else { + if (*mx + 2 >= max) return CERR_BufferOverflow; + tstr[(*mx)++] = (KMX_WCHAR) BaseChar; + } + } + tstr[*mx] = 0; + } + + return CERR_None; +} + +KMX_DWORD process_set_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // I3437 +{ + /* set( <'='> ), layer */ + PKMX_WCHAR temp = new KMX_WCHAR[GLOBAL_BUFSIZE], r; + KMX_DWORD msg; + + if ((msg = GetXString(fk, q, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } + + KMX_DWORD dwStoreID; + + msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); + delete[] temp; + if (msg != CERR_None) return msg; + + tstr[(*mx)++] = UC_SENTINEL; + tstr[(*mx)++] = (KMX_WCHAR)CODE_SETSYSTEMSTORE; + tstr[(*mx)++] = (KMX_WCHAR)(dwSystemID + 1); + tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); + tstr[(*mx)] = 0; + return CERR_None; +} + +KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +{ + /* set( <'='> */ + PKMX_WCHAR r = q, s = q; // I3440 + while (*s && *s != u' ' && *s != u'=') s++; + r = s; + while (*s == u' ') s++; + if (*s != '=') return CERR_InvalidSet; + s++; + while (*s == ' ') s++; + *r = 0; + r = q; + + KMX_DWORD i, code; + + if (r[0] == '&') + { + VERIFY_KEYBOARD_VERSION((PFILE_KEYBOARD) fk, VERSION_90, CERR_90FeatureOnly_SetSystemStores); // I3437 + for (i = 0; StoreTokens[i]; i++) + { + if (u16icmp(r, StoreTokens[i]) == 0) break; + } + if (!StoreTokens[i]) return CERR_SetSystemStore_NotFound; + code = CODE_SETSYSTEMSTORE; + } + else + { + KMX_WCHAR *context = NULL; + KMX_WCHAR sep_eq[3] = u" ="; + PKMX_WCHAR r = u16tok(q, sep_eq, &context); // I3481 + + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(r, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); + code = CODE_SETOPT; + } + + PKMX_WCHAR temp = new KMX_WCHAR[GLOBAL_BUFSIZE]; + + KMX_DWORD msg; + + //r = wcstok(NULL, L" ="); + + if ((msg = GetXString(fk, s, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } + + KMX_DWORD dwStoreID; + + msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); + delete[] temp; + if (msg != CERR_None) return msg; + + tstr[(*mx)++] = UC_SENTINEL; + tstr[(*mx)++] = (KMX_WCHAR)code; + tstr[(*mx)++] = (KMX_WCHAR)(i + 1); + tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); + tstr[(*mx)] = 0; + return CERR_None; +} + +KMX_DWORD process_save(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) +{ + /* save() */ + KMX_DWORD i; + for (i = 0; i < fk->cxStoreArray; i++) + { + if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); + + tstr[(*mx)++] = UC_SENTINEL; + tstr[(*mx)++] = CODE_SAVEOPT; + tstr[(*mx)++] = (KMX_WCHAR)(i + 1); + tstr[(*mx)] = 0; + return CERR_None; +} + +int xatoi(PKMX_WCHAR *p) +{ + PKMX_WCHAR endptr; + int n; + + switch (towupper(**p)) + { + case 'U': + (*p)++; + if (**p != '+') return 0; + (*p)++; + n = (int)u16tol(*p, &endptr, 16); + *p = endptr; + break; + case 'X': + (*p)++; + n = (int)u16tol(*p, &endptr, 16); + *p = endptr; + break; + case 'D': + (*p)++; + n = (int)u16tol(*p, &endptr, 10); + *p = endptr; + break; + default: + n = (int)u16tol(*p, &endptr, 8); + *p = endptr; + break; + } + return n; +} + +int GetGroupNum(PFILE_KEYBOARD fk, PKMX_WCHAR p) +{ + PFILE_GROUP gp; + KMX_DWORD i; + + for (i = 0, gp = fk->dpGroupArray; i < fk->cxGroupArray; gp++, i++) + { + if (u16icmp(gp->szName, p) == 0) return i + 1; + } + return 0; +} + + +KMX_DWORD ProcessEthnologueStore(PKMX_WCHAR p) // I2646 +{ + KMX_DWORD res = CERR_None; + PKMX_WCHAR q = NULL; + while (*p) + { + while (u16chr(u" ,;", *p)) + { + if (*p != ' ') res = CWARN_PunctuationInEthnologueCode; + p++; + } + if (q == p) return CERR_InvalidEthnologueCode; + if (*p) + { + for (int i = 0; i < 3; i++) + { + if (!iswalpha(*p)) return CERR_InvalidEthnologueCode; + p++; + } + } + q = p; + } + return res; +} + +#define K_HOTKEYSHIFTFLAGS (K_SHIFTFLAG | K_CTRLFLAG | K_ALTFLAG | ISVIRTUALKEY) + +KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) +{ + PKMX_WCHAR q, r; + KMX_DWORD sFlag; + int j, i; + + *hk = 0; + + if (*p == UC_SENTINEL && *(p + 1) == CODE_EXTENDED) { + KMX_WORD Key = *(p + 3); + KMX_WORD ShiftFlags = *(p + 2); + + // Convert virtual key to hotkey (different bitflags) + + if (ShiftFlags & ~K_HOTKEYSHIFTFLAGS) { + AddWarning(CWARN_HotkeyHasInvalidModifier); + } + + if (ShiftFlags & K_SHIFTFLAG) *hk |= HK_SHIFT; + if (ShiftFlags & K_CTRLFLAG) *hk |= HK_CTRL; + if (ShiftFlags & K_ALTFLAG) *hk |= HK_ALT; + + *hk |= Key; + + return CERR_None; + } + + q = (PKMX_WCHAR) u16chr(p, '['); + if (q) + { + q++; + sFlag = 0; + + do + { + while (iswspace(*q)) q++; + + if (u16nicmp(q, u"ALT", 3) == 0) sFlag |= HK_ALT, q += 3; + else if (u16nicmp(q, u"CTRL", 4) == 0) sFlag |= HK_CTRL, q += 4; + else if (u16nicmp(q, u"SHIFT", 5) == 0) sFlag |= HK_SHIFT, q += 5; + else if (towupper(*q) != 'K') return CERR_InvalidToken; + } while (towupper(*q) != 'K'); + + r = (PKMX_WCHAR) u16chr(q, ']'); + if (r) + { + r--; + while (iswspace(*r) && r > q) r--; + r++; + } + else return CERR_NoTokensFound; + + j = (int)(r - q); + + for (i = 0; i <= VK__MAX; i++) // I3438 + if (j == (int) u16len(VKeyNames[i]) && u16nicmp(q, VKeyNames[i], j) == 0) break; + + if (i == VK__MAX + 1) return CERR_InvalidToken; // I3438 + + *hk = i | sFlag; + + return CERR_None; + } + + q = GetDelimitedString(&p, u"\"\"", GDS_CUTLEAD | GDS_CUTFOLL); + if (q) + { + if (u16chr(q, '^')) *hk |= HK_CTRL; + if (u16chr(q, '+')) *hk |= HK_SHIFT; + if (u16chr(q, '%')) *hk |= HK_ALT; + q = (PKMX_WCHAR) u16chr(q, 0) - 1; + *hk |= *q; + return CERR_None; + } + + return CERR_CodeInvalidInThisSection; +} + + +void SetChecksum(PKMX_BYTE buf, PKMX_DWORD CheckSum, KMX_DWORD sz) +{ + BuildCRCTable(); + *CheckSum = CalculateBufferCRC(buf, sz); +} + + +KMX_BOOL kmcmp::CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall) +{ + PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; + if (fIsStore && !sp->fIsStore) + { + if (sp->fIsDebug || sp->fIsOption || sp->fIsReserved || sp->fIsCall) + AddWarningBool(CWARN_StoreAlreadyUsedAsOptionOrCall); + sp->fIsStore = TRUE; + } + else if (fIsOption && !sp->fIsOption) + { + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsCall) + AddWarningBool(CWARN_StoreAlreadyUsedAsStoreOrCall); + sp->fIsOption = TRUE; + } + else if (fIsCall && !sp->fIsCall) + { + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsOption) + AddWarningBool(CWARN_StoreAlreadyUsedAsStoreOrOption); + sp->fIsCall = TRUE; + } + + return TRUE; +} + +KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, FILE* fp_out) +{ + PFILE_GROUP fgp; + PFILE_STORE fsp; + PFILE_KEY fkp; + + PCOMP_KEYBOARD ck; + PCOMP_GROUP gp; + PCOMP_STORE sp; + PCOMP_KEY kp; + PKMX_BYTE buf; + size_t offset; + size_t size; + KMX_DWORD i, j; + + // Calculate how much memory to allocate + + size = sizeof(COMP_KEYBOARD) + + fk->cxGroupArray * sizeof(COMP_GROUP) + + fk->cxStoreArray * sizeof(COMP_STORE) + + /*wcslen(fk->szName)*2 + 2 + + wcslen(fk->szCopyright)*2 + 2 + + wcslen(fk->szLanguageName)*2 + 2 + + wcslen(fk->szMessage)*2 + 2 +*/ + fk->dwBitmapSize; + + for (i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) + { + if (kmcmp::FSaveDebug) size += u16len(fgp->szName) * 2 + 2; + size += fgp->cxKeyArray * sizeof(COMP_KEY); + for (j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) + { + size += u16len(fkp->dpOutput) * 2 + 2; + size += u16len(fkp->dpContext) * 2 + 2; + } + + if (fgp->dpMatch) size += u16len(fgp->dpMatch) * 2 + 2; + if (fgp->dpNoMatch) size += u16len(fgp->dpNoMatch) * 2 + 2; + } + + for (i = 0; i < fk->cxStoreArray; i++) + { + size += u16len(fk->dpStoreArray[i].dpString) * 2 + 2; + if (kmcmp::FSaveDebug || fk->dpStoreArray[i].fIsOption) size += u16len(fk->dpStoreArray[i].szName) * 2 + 2; + } + + buf = new KMX_BYTE[size]; + if (!buf) return CERR_CannotAllocateMemory; + memset(buf, 0, size); + + ck = (PCOMP_KEYBOARD)buf; + + ck->dwIdentifier = FILEID_COMPILED; + ck->dwFileVersion = fk->version; + ck->dwCheckSum = 0; // do checksum afterwards. + ck->KeyboardID = fk->KeyboardID; + ck->IsRegistered = TRUE; // I5135 + ck->cxStoreArray = fk->cxStoreArray; + ck->cxGroupArray = fk->cxGroupArray; + ck->StartGroup[0] = fk->StartGroup[0]; + ck->StartGroup[1] = fk->StartGroup[1]; + ck->dwHotKey = fk->dwHotKey; + + ck->dwFlags = fk->dwFlags; + + offset = sizeof(COMP_KEYBOARD); + + /*ck->dpLanguageName = offset; + wcscpy((PWSTR)(buf + offset), fk->szLanguageName); + offset += wcslen(fk->szLanguageName)*2 + 2; + + ck->dpName = offset; + wcscpy((PWSTR)(buf + offset), fk->szName); + offset += wcslen(fk->szName)*2 + 2; + + ck->dpCopyright = offset; + wcscpy((PWSTR)(buf + offset), fk->szCopyright); + offset += wcslen(fk->szCopyright)*2 + 2; + + ck->dpMessage = offset; + wcscpy((PWSTR)(buf + offset), fk->szMessage); + offset += wcslen(fk->szMessage)*2 + 2;*/ + + ck->dpStoreArray = (KMX_DWORD)offset; + sp = (PCOMP_STORE)(buf + offset); + fsp = fk->dpStoreArray; + offset += sizeof(COMP_STORE) * ck->cxStoreArray; + for (i = 0; i < ck->cxStoreArray; i++, sp++, fsp++) + { + sp->dwSystemID = fsp->dwSystemID; + sp->dpString = (KMX_DWORD)offset; + u16ncpy((PKMX_WCHAR)(buf + offset), fsp->dpString, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fsp->dpString) * 2 + 2; + + if (kmcmp::FSaveDebug || fsp->fIsOption) + { + sp->dpName = (KMX_DWORD)offset; + u16ncpy((PKMX_WCHAR)(buf + offset), fsp->szName, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fsp->szName) * 2 + 2; + } + else sp->dpName = 0; + } + + ck->dpGroupArray = (KMX_DWORD)offset; + gp = (PCOMP_GROUP)(buf + offset); + fgp = fk->dpGroupArray; + + offset += sizeof(COMP_GROUP) * ck->cxGroupArray; + + for (i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) + { + gp->cxKeyArray = fgp->cxKeyArray; + gp->fUsingKeys = fgp->fUsingKeys; + + gp->dpMatch = gp->dpNoMatch = 0; + + if (fgp->dpMatch) + { + gp->dpMatch = (KMX_DWORD)offset; + u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpMatch, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fgp->dpMatch) * 2 + 2; + } + if (fgp->dpNoMatch) + { + gp->dpNoMatch = (KMX_DWORD)offset; + u16ncpy((PKMX_WCHAR)(buf + offset), fgp->dpNoMatch, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fgp->dpNoMatch) * 2 + 2; + } + + if (kmcmp::FSaveDebug) + { + gp->dpName = (KMX_DWORD)offset; + u16ncpy((PKMX_WCHAR)(buf + offset), fgp->szName, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fgp->szName) * 2 + 2; + } + else gp->dpName = 0; + + gp->dpKeyArray = (KMX_DWORD)offset; + kp = (PCOMP_KEY )(buf + offset); + fkp = fgp->dpKeyArray; + offset += gp->cxKeyArray * sizeof(COMP_KEY); + for (j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) + { + kp->_reserved = 0; + kp->Key = fkp->Key; + if (kmcmp::FSaveDebug) kp->Line = fkp->Line; else kp->Line = 0; + kp->ShiftFlags = fkp->ShiftFlags; + kp->dpOutput = (KMX_DWORD)offset; + u16ncpy((PKMX_WCHAR)(buf + offset), fkp->dpOutput, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fkp->dpOutput) * 2 + 2; + kp->dpContext = (KMX_DWORD)offset; + u16ncpy((PKMX_WCHAR)(buf + offset), fkp->dpContext, (size - offset) / sizeof(KMX_WCHAR)); // I3481 // I3641 + offset += u16len(fkp->dpContext) * 2 + 2; + } + } + + ck->dwBitmapSize = fk->dwBitmapSize; + ck->dpBitmapOffset = (KMX_DWORD)offset; + memcpy(buf + offset, fk->lpBitmap, fk->dwBitmapSize); + offset += fk->dwBitmapSize; + + if (offset != size) { + delete[] buf; + return CERR_SomewhereIGotItWrong; + } + + SetChecksum(buf, &ck->dwCheckSum, (KMX_DWORD)size); + + KMX_DWORD dwBytesWritten = 0; + dwBytesWritten = fwrite(buf,1, (KMX_DWORD)size , fp_out); + + if (dwBytesWritten != size) { + delete[] buf; + return CERR_UnableToWriteFully; + } + + delete[] buf; + + return CERR_None; +} + +KMX_DWORD ReadLine(FILE* fp_in , PKMX_WCHAR wstr, KMX_BOOL PreProcess) +{ + KMX_DWORD len; + PKMX_WCHAR p; + KMX_BOOL LineCarry = FALSE, InComment = FALSE; + KMX_DWORD n; + KMX_WCHAR currentQuotes = 0; + KMX_WCHAR str[LINESIZE + 3]; + len = fread( str , 1 ,LINESIZE * 2,fp_in); + if (ferror(fp_in) ) return CERR_CannotReadInfile; + len /= 2; + str[len] = 0; auto cur = ftell(fp_in); + fseek(fp_in, 0, SEEK_END); + auto fsize = ftell(fp_in); + fseek(fp_in, cur, SEEK_SET); + + if (cur == fsize) + + // \r\n is still added here even though Linux doesn`t use \r. + // This is to ensure to still have a working windows-only-version + u16ncat(str, u"\r\n", _countof(str)); // I3481 // Always a "\r\n" to the EOF, avoids funny bugs + + if (len == 0) return CERR_EndOfFile; + + // neccessary to add this block for using on non-windows platforms (removes all \r for platforms that use \n instead of \r\n) + for (p = str, n = 0; n < len; n++, p++) { + if (*p == L'\r') + *p = L' '; + } + + // \r is still left in this block even though Linux doesn`t use \r. + // This is to ensure to still have a working windows-only-version + for (p = str, n = 0; n < len; n++, p++) + { + if (currentQuotes != 0) + { + if (*p == L'\n') + { + *p = 0; // I2525 + u16ncpy(wstr, str, LINESIZE); // I3481 + return (PreProcess ? CERR_None : CERR_UnterminatedString); + } + if (*p == currentQuotes) currentQuotes = 0; + continue; + } + if (InComment) { + if (*p == L'\n') break; + *p = L' '; + continue; + } + if(*p == L'\\') { + LineCarry = TRUE; + *p = L' '; + continue; + } + if (LineCarry) + { + switch (*p) + { + case L' ': + case L'\t': + case L'\r': + *p = L' '; + continue; + case L'\n': + kmcmp::currentLine++; + LineCarry = FALSE; + *p = L' '; + continue; + } + *p = 0; // I2525 + u16ncpy(wstr, str, LINESIZE); // I3481 + return (PreProcess ? CERR_None : CERR_InvalidLineContinuation); + } + + if (*p == L'\n') break; + switch (*p) + { + case L'c': + case L'C': + if ((p == str || iswspace(*(p - 1))) && iswspace(*(p + 1))) { + InComment = TRUE; + *p = L' '; + } + continue; + case L'\r': + case L'\t': + *p = L' '; + continue; + case L'\'': + case L'\"': + currentQuotes = *p; + continue; + } + } + + if (n == len) + { + str[LINESIZE - 1] = 0; // I2525 + u16ncpy(wstr, str, LINESIZE); // I3481 + if (len == LINESIZE) + return (PreProcess ? CERR_None : CERR_LineTooLong); + } + + if (*p == L'\n') kmcmp::currentLine++; + + fseek(fp_in, -(int)(len * 2 - (int)(p - str) * 2 - 2), SEEK_CUR); + + p--; + while (p >= str && iswspace(*p)) p--; + p++; + *p++ = L'\n'; + *p = 0; + // trim spaces now, why not? + u16ncpy(wstr, str, LINESIZE); // I3481 + + return CERR_None; +} + +KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode) +{ + PKMX_WCHAR q; + p = (const PKMX_WCHAR) u16chr(p, '>'); + + if (!p) return CERR_NoTokensFound; + + p++; + + return GetXString(fk, p, u"c\n", buf, bufsize, offset, &q, TRUE, IsUnicode); +} + +void safe_wcsncpy(PKMX_WCHAR out, PKMX_WCHAR in, int cbMax) +{ + u16ncpy(out, in, cbMax - 1); // I3481 + out[cbMax - 1] = 0; +} + +KMX_BOOL IsSameToken(PKMX_WCHAR *p, KMX_WCHAR const * token) +{ + PKMX_WCHAR q; + q = *p; + while (iswspace(*q)) q++; + if (u16nicmp(q, token, u16len(token)) == 0) + { + q += u16len(token); + while (iswspace(*q)) q++; + *p = q; + return TRUE; + } + return FALSE; +} + +KMX_DWORD ImportBitmapFile(PFILE_KEYBOARD fk, PKMX_WCHAR szName, PKMX_DWORD FileSize, PKMX_BYTE *Buf) +{ + FILE *fp; + KMX_WCHAR szNewName[260]; + + if (IsRelativePath(szName)) + { + PKMX_WCHAR WCompileDir = strtowstr(kmcmp::CompileDir); + u16ncpy(szNewName, WCompileDir, _countof(szNewName)); // I3481 + u16ncat(szNewName,szName, _countof(szNewName )); // I3481 + } + else + u16ncpy(szNewName, szName, _countof(szNewName)); // I3481 + + fp=Open_File(szNewName, u"rb"); + + if ( fp == NULL) + { + // else if filename.bmp is not in the folder -> attempt to open filename.bmp.bmp ! + if ( u16cmp(szNewName+u16len(szNewName)-4, u".bmp") ) + u16ncat(szNewName, u".bmp", _countof(szNewName)); // I3481 + + fp= Open_File(szNewName, u"rb"); + + if ( fp == NULL) + return CERR_CannotReadBitmapFile; + } + + KMX_DWORD msg; + if ((msg = CheckFilenameConsistency(szNewName, FALSE)) != CERR_None) { + return msg; + } + + fseek(fp, 0, SEEK_END); + *FileSize = ftell(fp); + fseek(fp ,0,SEEK_SET); + if (*FileSize < 0) { + fclose(fp); + return CERR_CannotReadBitmapFile; + } + + if (*FileSize < 2) return CERR_CannotReadBitmapFile; + *Buf = new KMX_BYTE[*FileSize]; + + if (fread(*Buf, 1, *FileSize, fp) < (size_t) *FileSize) { + delete[] * Buf; + *Buf = NULL; + return CERR_CannotReadBitmapFile; + } + + fclose(fp); + + /* Test for version 7.0 icon support */ + if (*((PKMX_CHAR)*Buf) != 'B' && *(((PKMX_CHAR)*Buf) + 1) != 'M') { + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + } + + return CERR_None; +} + +int atoiW(PKMX_WCHAR p) +{ + PKMX_STR q = wstrtostr(p); + int i = atoi(q); + delete[] q; + return i; +} + +KMX_DWORD kmcmp::CheckUTF16(int n) +{ + const int res[] = { + 0xFDD0, 0xFDD1, 0xFDD2, 0xFDD3, 0xFDD4, 0xFDD5, 0xFDD6, 0xFDD7, + 0xFDD8, 0xFDD9, 0xFDDA, 0xFDDB, 0xFDDC, 0xFDDD, 0xFDDE, 0xFDDF, + 0xFDE0, 0xFDE1, 0xFDE2, 0xFDE3, 0xFDE4, 0xFDE5, 0xFDE6, 0xFDE7, + 0xFDE8, 0xFDE9, 0xFDEA, 0xFDEB, 0xFDEC, 0xFDED, 0xFDEE, 0xFDEF, + 0xFFFF, 0xFFFE, 0 }; + + if (n == 0) return CERR_ReservedCharacter; + for (int i = 0; res[i] > 0; i++) + if (n == res[i]) + { + AddWarning(CWARN_ReservedCharacter); + break; + } + return CERR_None; +} + +KMX_DWORD kmcmp::UTF32ToUTF16(int n, int *n1, int *n2) +{ + *n2 = -1; + if (n <= 0xFFFF) + { + *n1 = n; + if (n >= 0xD800 && n <= 0xDFFF) AddWarning(CWARN_UnicodeSurrogateUsed); + return kmcmp::CheckUTF16(*n1); + } + + if ((n & 0xFFFF) == 0xFFFF || (n & 0xFFFF) == 0xFFFE) AddWarning(CWARN_ReservedCharacter); + if (n < 0 || n > 0x10FFFF) return CERR_InvalidCharacter; + n = n - 0x10000; + *n1 = (n / 0x400) + 0xD800; + *n2 = (n % 0x400) + 0xDC00; + KMX_DWORD msg; + if ((msg = kmcmp::CheckUTF16(*n1)) != CERR_None) return msg; + return kmcmp::CheckUTF16(*n2); +} + +KMX_DWORD BuildVKDictionary(PFILE_KEYBOARD fk) +{ + KMX_DWORD i; + size_t len = 0; + if (fk->cxVKDictionary == 0) return CERR_None; + for (i = 0; i < fk->cxVKDictionary; i++) + { + len += u16len(fk->dpVKDictionary[i].szName) + 1; + } + PKMX_WCHAR storeval = new KMX_WCHAR[len], p = storeval; + for (i = 0; i < fk->cxVKDictionary; i++) + { + u16ncpy(p, fk->dpVKDictionary[i].szName, len - (size_t)(p - storeval)); // I3481 + p = (PKMX_WCHAR) u16chr(p, 0); + *p = ' '; + p++; + } + + p--; + *p = 0; + + KMX_DWORD dwStoreID; + KMX_DWORD msg = AddStore(fk, TSS_VKDICTIONARY, storeval, &dwStoreID); + delete[] storeval; + return msg; +} + +int GetVKCode(PFILE_KEYBOARD fk, PKMX_WCHAR p) +{ + KMX_DWORD i; + + for (i = 0; i < fk->cxVKDictionary; i++) + if (u16icmp(fk->dpVKDictionary[i].szName, p) == 0) + return i + VK__MAX + 1; // 256 + + if (fk->cxVKDictionary % 10 == 0) + { + PFILE_VKDICTIONARY pvk = new FILE_VKDICTIONARY[fk->cxVKDictionary + 10]; + memcpy(pvk, fk->dpVKDictionary, fk->cxVKDictionary * sizeof(FILE_VKDICTIONARY)); + delete fk->dpVKDictionary; + fk->dpVKDictionary = pvk; + } + u16ncpy(fk->dpVKDictionary[fk->cxVKDictionary].szName, p, _countof(fk->dpVKDictionary[fk->cxVKDictionary].szName) ); // I3481 + fk->dpVKDictionary[fk->cxVKDictionary].szName[SZMAX_VKDICTIONARYNAME - 1] = 0; + + fk->cxVKDictionary++; + return fk->cxVKDictionary + VK__MAX; // 256-1 +} + +int GetDeadKey(PFILE_KEYBOARD fk, PKMX_WCHAR p) +{ + KMX_DWORD i; + + for (i = 0; i < fk->cxDeadKeyArray; i++) + if (u16icmp(fk->dpDeadKeyArray[i].szName, p) == 0) + return i + 1; + + if (fk->cxDeadKeyArray % 10 == 0) + { + PFILE_DEADKEY dk = new FILE_DEADKEY[fk->cxDeadKeyArray + 10]; + memcpy(dk, fk->dpDeadKeyArray, fk->cxDeadKeyArray * sizeof(FILE_DEADKEY)); + delete[] fk->dpDeadKeyArray; + fk->dpDeadKeyArray = dk; + } + u16ncpy(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName,p, _countof(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName)); // I3481 + fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName[SZMAX_DEADKEYNAME - 1] = 0; + + fk->cxDeadKeyArray++; + return fk->cxDeadKeyArray; +} + +void kmcmp::RecordDeadkeyNames(PFILE_KEYBOARD fk) +{ + KMX_WCHAR buf[SZMAX_DEADKEYNAME + 16]; + KMX_DWORD i; + for (i = 0; i < fk->cxDeadKeyArray; i++) + { + u16sprintf(buf, _countof(buf), L"%ls%d ", u16fmt(DEBUGSTORE_DEADKEY).c_str(), (int)i); + u16ncat(buf, fk->dpDeadKeyArray[i].szName, _countof(buf)); + + AddDebugStore(fk, buf); + } +} + +KMX_BOOL kmcmp::IsValidCallStore(PFILE_STORE fs) +{ + int i; + PKMX_WCHAR p; + for (i = 0, p = fs->dpString; *p; p++) + if (*p == ':') i++; + else if (!((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '.' || + *p == '_')) + return FALSE; + + return i == 1; +} + +FILE* CreateTempFile() +{ + return tmpfile(); +} + +/////////////////// + +FILE* UTF16TempFromUTF8(FILE* fp_in , KMX_BOOL hasPreamble) +{ + FILE *fp_out = CreateTempFile(); + if(fp_out == NULL) // I3228 // I3510 + { + fclose(fp_in); + return NULL; //return INVALID_HANDLE_VALUE; _S2 can I exchange that? + } + + PKMX_BYTE buf, p; + PKMX_WCHAR outbuf, poutbuf; + KMX_DWORD len; + KMX_DWORD len2; + KMX_WCHAR prolog = 0xFEFF; + fwrite(&prolog,2, 1, fp_out); + + fseek(fp_in, 0, SEEK_END); + len = ftell(fp_in); + fseek(fp_in, 0, SEEK_SET); + if (hasPreamble) { + fseek( fp_in,3,SEEK_SET); // Cut off UTF-8 marker + len -= 3; + } + + buf = new KMX_BYTE[len + 1]; // null terminated + outbuf = new KMX_WCHAR[len + 1]; + + len2= fread(buf,1,len,fp_in); + if (len2) { + buf[len2] = 0; + p = buf; + poutbuf = outbuf; + if (hasPreamble) { + // We have a preamble, so we attempt to read as UTF-8 and allow conversion errors to be filtered. This is not great for a + // compiler but matches existing behaviour -- in future versions we may not do lenient conversion. + ConvertUTF8toUTF16(&p, &buf[len2], (UTF16 **)&poutbuf, (const UTF16 *)&outbuf[len], lenientConversion); + fwrite(outbuf, (KMX_DWORD)(poutbuf - outbuf) * 2 , 1, fp_out); + } + else { + // No preamble, so we attempt to read as strict UTF-8 and fall back to ANSI if that fails + ConversionResult cr = ConvertUTF8toUTF16(&p, &buf[len2], (UTF16 **)&poutbuf, (const UTF16 *)&outbuf[len], strictConversion); + if (cr == sourceIllegal) { + // Not a valid UTF-8 file, so fall back to ANSI + // AddCompileError(CHINT_NonUnicodeFile); + // note, while this message is defined, for now we will not emit it + // because we don't support HINT/INFO messages yet and we don't want + // this to cause a blocking compile at this stage + // do strtowstr only when no invalid characters are found + if( p==0){ + poutbuf = strtowstr((PKMX_STR)buf); + fwrite(poutbuf, (KMX_DWORD)u16len(poutbuf) * 2 , 1, fp_out); + delete[] poutbuf; + } + else + AddCompileError(CERR_InvalidCharacter); + } + + else { + fwrite(outbuf, (KMX_DWORD)(poutbuf - outbuf) * 2 , 1, fp_out); + } + } + } + + fclose( fp_in); + delete[] buf; + delete[] outbuf; + fseek( fp_out,2,SEEK_SET); + return fp_out; +} + +PFILE_STORE FindSystemStore(PFILE_KEYBOARD fk, KMX_DWORD dwSystemID) +{ + assert(fk != NULL); + assert(dwSystemID != 0); + + PFILE_STORE sp = fk->dpStoreArray; + for (KMX_DWORD i = 0; i < fk->cxStoreArray; i++, sp++) { + if (sp->dwSystemID == dwSystemID) { + return sp; + } + } + return NULL; +} diff --git a/developer/src/kmcmplib/src/CompilerInterfaces.cpp b/developer/src/kmcmplib/src/CompilerInterfaces.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09afa1d2cbb8aaab1316493266ecd78c401ffc4e --- /dev/null +++ b/developer/src/kmcmplib/src/CompilerInterfaces.cpp @@ -0,0 +1,368 @@ +#include "pch.h" + +#include +#include +#include "kmcmplib.h" +#include "filesystem.h" +#include "CheckFilenameConsistency.h" +#include "CheckNCapsConsistency.h" +#include "DeprecationChecks.h" +#include "versioning.h" +#include "../../../../common/windows/cpp/include/ConvertUTF.h" +#include "../../../../common/windows/cpp/include/keymanversion.h" + +#define SetError(err) { if(AddCompileError(err) || (err & CERR_FATAL)) return FALSE; } + +bool CompileKeyboardHandle(FILE* fp_in, PFILE_KEYBOARD fk); + +EXTERN bool kmcmp_SetCompilerOptions(KMCMP_COMPILER_OPTIONS* options) { + //printf("°°-> changed to SetCompilerOptions() of kmcmplib \n"); + if(!options || options->dwSize < sizeof(KMCMP_COMPILER_OPTIONS)) { + return FALSE; + } + kmcmp::FShouldAddCompilerVersion = options->ShouldAddCompilerVersion; + return TRUE; +} + +#ifdef __EMSCRIPTEN__ + +/* + WASM interface for compiler message callback +*/ +EM_JS(int, wasm_msgproc, (int line, int msgcode, char* text, char* context), { + const proc = globalThis[context]; + if(!proc || typeof proc != 'function') { + console.log(`[${line}: ${msgcode}: ${UTF8ToString(text)}]`); + return 0; + } else { + return proc(line, msgcode, UTF8ToString(text)); + } +}); + +int wasm_CompilerMessageProc(int line, uint32_t dwMsgCode, char* szText, void* context) { + char* msgProc = static_cast(context); + return wasm_msgproc(line, dwMsgCode, szText, msgProc); +} + +EXTERN bool kmcmp_Wasm_SetCompilerOptions(int ShouldAddCompilerVersion) { + KMCMP_COMPILER_OPTIONS options; + options.dwSize = sizeof(KMCMP_COMPILER_OPTIONS); + options.ShouldAddCompilerVersion = ShouldAddCompilerVersion; + return kmcmp_SetCompilerOptions(&options); +} + +EXTERN bool kmcmp_Wasm_CompileKeyboardFile(char* pszInfile, + char* pszOutfile, int ASaveDebug, int ACompilerWarningsAsErrors, + int AWarnDeprecatedCode, char* msgProc +) { + return kmcmp_CompileKeyboardFile( + pszInfile, + pszOutfile, + ASaveDebug, + ACompilerWarningsAsErrors, + AWarnDeprecatedCode, + wasm_CompilerMessageProc, + msgProc + ); +} +#endif + +EXTERN bool kmcmp_CompileKeyboardFile(char* pszInfile, + char* pszOutfile, bool ASaveDebug, bool ACompilerWarningsAsErrors, + bool AWarnDeprecatedCode, kmcmp_CompilerMessageProc pMsgproc, void* AmsgprocContext +) { + FILE* fp_in = NULL; + FILE* fp_out = NULL; + KMX_CHAR str[260]; + + //printf("°°-> changed to CompileKeyboardFile() of kmcmplib \n"); + + kmcmp::FSaveDebug = ASaveDebug; + kmcmp::FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 + AWarnDeprecatedCode_GLOBAL_LIB = AWarnDeprecatedCode; + + kmcmp::CompileTarget = CKF_KEYMAN; + + if (!pMsgproc || !pszInfile || !pszOutfile) SetError(CERR_BadCallParams); + + PKMX_STR p; + + if ((p = strrchr_slash(pszInfile)) != nullptr) + { + strncpy(kmcmp::CompileDir, pszInfile, (int)(p - pszInfile + 1)); // I3481 + kmcmp::CompileDir[(int)(p - pszInfile + 1)] = 0; + } + else + kmcmp::CompileDir[0] = 0; + + msgproc = pMsgproc; + msgprocContext = AmsgprocContext; + kmcmp::currentLine = 0; + kmcmp::nErrors = 0; + + fp_in = Open_File(pszInfile, "rb"); + + if (fp_in == NULL) { + SetError(CERR_InfileNotExist); + } + + // Transfer the file to a memory stream for processing UTF-8 or ANSI to UTF-16? + // What about really large files? Transfer to a temp file... + if (!fread(str, 1, 3, fp_in)) { + fclose(fp_in); + SetError(CERR_CannotReadInfile); + } + + fseek(fp_in, 0, SEEK_SET); + if (str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) + fp_in = UTF16TempFromUTF8(fp_in, TRUE); + else if (str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) + fseek(fp_in, 2, SEEK_SET); + else + fp_in = UTF16TempFromUTF8(fp_in, FALSE); + if (fp_in == NULL) { + SetError(CERR_CannotCreateTempfile); + } + + fp_out = Open_File(pszOutfile, "wb"); + + if (fp_out == NULL) { + SetError(CERR_CannotCreateOutfile); + } + + FILE_KEYBOARD fk; + kmcmp::CodeConstants = new kmcmp::NamedCodeConstants; + bool result = CompileKeyboardHandle(fp_in, &fk); + if(result) { + KMX_DWORD msg; + if ((msg = WriteCompiledKeyboard(&fk, fp_out)) != CERR_None) { + result = FALSE; + AddCompileError(msg); + } + } else { + AddCompileError(CERR_InvalidValue); + } + + fclose(fp_in); + fclose(fp_out); + + delete kmcmp::CodeConstants; + + if (kmcmp::nErrors > 0) + { + remove(pszOutfile); + return FALSE; + } + + return result; +} + + + +EXTERN bool kmcmp_CompileKeyboardFileToBuffer(char* pszInfile, void* pfkBuffer, bool ACompilerWarningsAsErrors, bool AWarnDeprecatedCode, + kmcmp_CompilerMessageProc pMsgproc, void* AmsgprocContext, int Target) // I4865 // I4866 +{ + //printf("°°-> changed to CompileKeyboardFileToBuffer() of kmcmplib \n"); + FILE* fp_in = NULL; + KMX_CHAR str[260]; + + kmcmp::FSaveDebug = TRUE; // I3681 + kmcmp::FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 + AWarnDeprecatedCode_GLOBAL_LIB = AWarnDeprecatedCode; + kmcmp::CompileTarget = Target; + + if (!pMsgproc || !pszInfile || !pfkBuffer) { + SetError(CERR_BadCallParams); + } + + PKMX_STR p; + + if ((p = strrchr_slash(pszInfile)) != nullptr) { + strncpy(kmcmp::CompileDir, pszInfile, (int)(p - pszInfile + 1)); // I3481 + kmcmp::CompileDir[(int)(p - pszInfile + 1)] = 0; + } + else { + kmcmp::CompileDir[0] = 0; + } + + msgproc = pMsgproc; + msgprocContext = AmsgprocContext; + kmcmp::currentLine = 0; + kmcmp::nErrors = 0; + + fp_in = Open_File(pszInfile,"rb"); + + if (fp_in == NULL) { + SetError(CERR_InfileNotExist); + } + + // Transfer the file to a memory stream for processing UTF-8 or ANSI to UTF-16? + // What about really large files? Transfer to a temp file... + + if( !fread(str,1,3,fp_in)) + { + fclose(fp_in); + SetError(CERR_CannotReadInfile); + } + + fseek( fp_in,0,SEEK_SET); + if (str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) + fp_in = UTF16TempFromUTF8(fp_in, TRUE); + else if (str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) + fseek( fp_in,2,SEEK_SET); + else + fp_in = UTF16TempFromUTF8(fp_in, FALSE); + + kmcmp::CodeConstants = new kmcmp::NamedCodeConstants; + + bool result = CompileKeyboardHandle(fp_in, static_cast(pfkBuffer)); + delete kmcmp::CodeConstants; + fclose(fp_in); + + if (kmcmp::nErrors > 0) { + return FALSE; + } + return result; +} + +bool CompileKeyboardHandle(FILE* fp_in, PFILE_KEYBOARD fk) +{ + PKMX_WCHAR str, p; + + KMX_DWORD msg; + + kmcmp::FMnemonicLayout = FALSE; + + if (!fk) { + SetError(CERR_SomewhereIGotItWrong); + } + + str = new KMX_WCHAR[LINESIZE]; + if (!str) { + SetError(CERR_CannotAllocateMemory); + } + + fk->KeyboardID = 0; + fk->version = 0; + fk->dpStoreArray = NULL; + fk->dpGroupArray = NULL; + fk->cxStoreArray = 0; + fk->cxGroupArray = 0; + fk->StartGroup[0] = fk->StartGroup[1] = -1; + fk->szName[0] = 0; + fk->szCopyright[0] = 0; + fk->dwFlags = KF_AUTOMATICVERSION; + fk->currentGroup = 0xFFFFFFFF; + fk->currentStore = 0; + fk->cxDeadKeyArray = 0; + fk->dpDeadKeyArray = NULL; + fk->cxVKDictionary = 0; // I3438 + fk->dpVKDictionary = NULL; // I3438 + +/* fk->szMessage[0] = 0; + fk->szLanguageName[0] = 0;*/ + fk->dwBitmapSize = 0; + fk->dwHotKey = 0; + + kmcmp::BeginLine[BEGIN_ANSI] = -1; + kmcmp::BeginLine[BEGIN_UNICODE] = -1; + kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; + kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; + + + /* Add a store for the Keyman 6.0 copyright information string */ + + if(kmcmp::FShouldAddCompilerVersion) { + u16sprintf(str,LINESIZE, L"Created with Keyman Developer version %d.%d.%d.%d", KEYMAN_VersionMajor, KEYMAN_VersionMinor, KEYMAN_VersionPatch, 0); + AddStore(fk, TSS_KEYMANCOPYRIGHT, str); + } + + /* Add a system store for the Keyman edition number */ + u16sprintf(str, LINESIZE, L"%d", 0); // I3481 + AddStore(fk, TSS_CUSTOMKEYMANEDITION, str); + + PKMX_WCHAR tbuf = strtowstr((KMX_CHAR*) "Keyman"); + AddStore(fk, TSS_CUSTOMKEYMANEDITIONNAME, tbuf); + delete tbuf; + + // must preprocess for group and store names -> this isn't really necessary, but never mind! + while ((msg = ReadLine(fp_in, str, TRUE)) == CERR_None) + { + p = str; + switch (LineTokenType(&p)) + { + case T_VERSION: + *(p + 4) = 0; + if ((msg = AddStore(fk, TSS_VERSION, p)) != CERR_None) SetError(msg); + break; + + case T_GROUP: + if ((msg = ProcessGroupLine(fk, p)) != CERR_None) SetError(msg); + break; + + case T_STORE: + if ((msg = ProcessStoreLine(fk, p)) != CERR_None) SetError(msg); + break; + + default: + break; + } + } + + if (msg != CERR_EndOfFile) { + SetError(msg); + } + + fseek( fp_in,2,SEEK_SET); + kmcmp::currentLine = 0; + + /* Reindex the list of codeconstants after stores added */ + + kmcmp::CodeConstants->reindex(); + + /* ReadLine will automatically skip over $Keyman lines, and parse wrapped lines */ + while ((msg = ReadLine(fp_in, str, FALSE)) == CERR_None) + { + msg = ParseLine(fk, str); + if (msg != CERR_None) { + SetError(msg); + } + } + + if (msg != CERR_EndOfFile) { + SetError(msg); + } + + ProcessGroupFinish(fk); + + if (kmcmp::FSaveDebug) kmcmp::RecordDeadkeyNames(fk); + + /* Add the compiler version as a system store */ + if ((msg = kmcmp::AddCompilerVersionStore(fk)) != CERR_None) { + SetError(msg); + } + + if ((msg = BuildVKDictionary(fk)) != CERR_None) { + SetError(msg); // I3438 + } + + if ((msg = CheckFilenameConsistencyForCalls(fk)) != CERR_None) { + SetError(msg); + } + + delete str; + + if (!kmcmp::CheckKeyboardFinalVersion(fk)) { + return FALSE; + } + + /* Warn on inconsistent use of NCAPS */ + if (!kmcmp::FMnemonicLayout) { + CheckNCapsConsistency(fk); + } + + /* Flag presence of deprecated features */ + kmcmp::CheckForDeprecatedFeatures(fk); + + return TRUE; +} \ No newline at end of file diff --git a/developer/src/kmcmplib/src/DeprecationChecks.cpp b/developer/src/kmcmplib/src/DeprecationChecks.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef160cc96b8796866762e2fa4038d50ad29643e5 --- /dev/null +++ b/developer/src/kmcmplib/src/DeprecationChecks.cpp @@ -0,0 +1,53 @@ + +#include "pch.h" + +#include "compfile.h" +#include +#include "kmcmplib.h" +#include "DeprecationChecks.h" + +KMX_BOOL kmcmp::WarnDeprecatedHeader() { // I4866 +if( AWarnDeprecatedCode_GLOBAL_LIB){ + AddWarningBool(CWARN_HeaderStatementIsDeprecated); + } + return TRUE; +} + +/* Flag presence of deprecated features */ +KMX_BOOL kmcmp::CheckForDeprecatedFeatures(PFILE_KEYBOARD fk) { + /* + For Keyman 10, we deprecated: + // < Keyman 7 + #define TSS_LANGUAGE 4 + #define TSS_LAYOUT 5 + #define TSS_LANGUAGENAME 12 + #define TSS_ETHNOLOGUECODE 15 + + // Keyman 7 + #define TSS_WINDOWSLANGUAGES 29 + */ + int oldCurrentLine = kmcmp::currentLine; + KMX_DWORD i; + PFILE_STORE sp; + + if (!AWarnDeprecatedCode_GLOBAL_LIB) { + return TRUE; + } + + if (fk->version >= VERSION_100) { + for (i = 0, sp = fk->dpStoreArray; i < fk->cxStoreArray; i++, sp++) { + if (sp->dwSystemID == TSS_LANGUAGE || + sp->dwSystemID == TSS_LAYOUT || + sp->dwSystemID == TSS_LANGUAGENAME || + sp->dwSystemID == TSS_ETHNOLOGUECODE || + sp->dwSystemID == TSS_WINDOWSLANGUAGES) { + kmcmp::currentLine = sp->line; + AddWarningBool(CWARN_LanguageHeadersDeprecatedInKeyman10); + } + } + } + + kmcmp::currentLine = oldCurrentLine; + + return TRUE; +} diff --git a/developer/src/kmcmplib/src/DeprecationChecks.h b/developer/src/kmcmplib/src/DeprecationChecks.h new file mode 100644 index 0000000000000000000000000000000000000000..941b87f1a4d5dc367892d7ee8209d27a5fca88b6 --- /dev/null +++ b/developer/src/kmcmplib/src/DeprecationChecks.h @@ -0,0 +1,9 @@ +#pragma once + +#include "compfile.h" +#include "kmcmplib.h" + +namespace kmcmp{ +KMX_BOOL WarnDeprecatedHeader(); +KMX_BOOL CheckForDeprecatedFeatures(PFILE_KEYBOARD fk); +} diff --git a/developer/src/kmcmplib/src/Edition.cpp b/developer/src/kmcmplib/src/Edition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cdf82ee2f8f3c0da311c853f891b70096089e23e --- /dev/null +++ b/developer/src/kmcmplib/src/Edition.cpp @@ -0,0 +1,8 @@ + +#include "pch.h" +#include "Edition.h" + +int GetEdition() +{ + return ED_STANDARD; +} diff --git a/developer/src/kmcmplib/src/Edition.h b/developer/src/kmcmplib/src/Edition.h new file mode 100644 index 0000000000000000000000000000000000000000..26eb44c61609a1b7352f45b13f178a821ce5c424 --- /dev/null +++ b/developer/src/kmcmplib/src/Edition.h @@ -0,0 +1,12 @@ + +#ifndef _EDITION_H +#define _EDITION_H + +int GetEdition(); + +#define ED_DEMO 0 +#define ED_STANDARD 1 +#define ED_PRO 2 +#define ED_OEM 3 + +#endif diff --git a/developer/src/kmcmplib/src/NamedCodeConstants.cpp b/developer/src/kmcmplib/src/NamedCodeConstants.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d6c52df3ed3593996b808ef7b6ca05e78648576b --- /dev/null +++ b/developer/src/kmcmplib/src/NamedCodeConstants.cpp @@ -0,0 +1,346 @@ +/*2012 + Name: NamedCodeConstants + Copyright: Copyright (C) 2003-2017 SIL International. + Documentation: + Description: + Create Date: 19 Jul 2011 + + Modified Date: 13 Dec 2012 + Authors: mcdurdin + Related Files: + Dependencies: + + Bugs: + Todo: + Notes: + History: 19 Jul 2011 - mcdurdin - I2993 - Named code constants cause a warning 0x208D to appear + 24 Oct 2012 - mcdurdin - I3481 - V9.0 - Eliminate unsafe calls in C++ + 06 Feb 2012 - mcdurdin - I3056 - If file was not found in first search folder, named code constants failed to compile + 06 Feb 2012 - mcdurdin - I3056 - UTF-8 support for named code constants file + 03 Nov 2012 - mcdurdin - I3512 - V9.0 - Merge of I3056 - If file was not found in first search folder, named code constants failed to compile + 13 Dec 2012 - mcdurdin - I3641 - V9.0 - compiler dll buffer overrun bugs +*/ + +#include "pch.h" +#include +#include "NamedCodeConstants.h" +#include "CheckFilenameConsistency.h" +#include +#include "kmcompx.h" +#include "filesystem.h" + +using namespace kmcmp; + +int IsHangulSyllable(const KMX_WCHAR *codename, int *code); + +namespace kmcmp { + extern KMX_CHAR CompileDir[]; + + int __cdecl sort_entries(const void *elem1, const void *elem2) + { + return u16icmp( + ((NCCENTRY *)elem1)->name, + ((NCCENTRY *)elem2)->name); + } +} + +NamedCodeConstants::NamedCodeConstants() +{ + nEntries = 0; + entries = NULL; + nEntries_file = 0; + entries_file = NULL; + reindex(); +} + +NamedCodeConstants::~NamedCodeConstants() +{ + if(entries) delete entries; + if(entries_file) delete entries_file; +} + +void NamedCodeConstants::AddCode(int n, const KMX_WCHAR *p, KMX_DWORD storeIndex) +{ + if((nEntries_file % ALLOC_SIZE) == 0) + { + NCCENTRY *bn = new NCCENTRY[nEntries_file + ALLOC_SIZE]; + if(nEntries_file > 0) + { + memcpy(bn, entries_file, sizeof(NCCENTRY) * nEntries_file); + delete entries_file; + } + entries_file = bn; + } + + entries_file[nEntries_file].code = n; + u16ncpy(entries_file[nEntries_file].name, p, _countof(entries_file[nEntries_file].name)); // I3481 + entries_file[nEntries_file].name[MAX_ENAME] = 0; + + for (KMX_WCHAR *r = entries_file[nEntries_file].name; *r; r++) + if (iswblank(*r) && *r != '-') *r = '_'; + + entries_file[nEntries_file].storeIndex = storeIndex; + nEntries_file++; +} + +void NamedCodeConstants::AddCode_IncludedCodes(int n, const KMX_WCHAR *p) +{ + if((nEntries % ALLOC_SIZE) == 0) + { + NCCENTRY *bn = new NCCENTRY[nEntries + ALLOC_SIZE]; + if(nEntries > 0) + { + memcpy(bn, entries, sizeof(NCCENTRY) * nEntries); + delete entries; + } + entries = bn; + } + + entries[nEntries].code = n; + u16ncpy(entries[nEntries].name, p, MAX_ENAME); // I3481 + entries[nEntries].name[MAX_ENAME] = 0; + for (KMX_WCHAR *r = entries[nEntries].name; *r; r++) + if (iswblank(*r)) *r = '_'; + + entries[nEntries].storeIndex = 0xFFFFFFFFL; + nEntries++; +} + +// int __cdecl sort_entries(const void *elem1, const void *elem2) moved into namespace further up + +KMX_BOOL NamedCodeConstants::IntLoadFile(const KMX_CHAR *filename) +{ + const int str_size = 256; + FILE *fp = NULL; + + if (CheckFilenameConsistency(filename, FALSE) != NULL) { + return FALSE; + } + + fp = Open_File(filename, "rt"); + if(fp == NULL) { + return FALSE; // I3481 + } + + KMX_CHAR str[str_size], *p, *q, *context = NULL; + KMX_BOOL isEol , first = TRUE; + + while(fgets(str, str_size, fp)) + { + isEol = *(strchr(str, 0) - 1) == '\n'; + p = strtok_r(str, ";", &context); // I3481 + q = strtok_r(NULL, ";\n", &context); + if(p && q) + { + if(first && *p == (KMX_CHAR)0xEF && *(p+1) == (KMX_CHAR)0xBB && *(p+2) == (KMX_CHAR)0xBF) p += 3; // I3056 UTF-8 // I3512 + first = FALSE; + strupr(q); // I3481 // I3641 + int n = strtol(p, NULL, 16); + if (*q != '<') { + PKMX_WCHAR q0 = strtowstr(q); + AddCode_IncludedCodes(n, q0); + delete[] q0; + } + } + if(!isEol ) + { + while(fgets(str, str_size, fp)) if(*(strchr(str, 0)-1) == '\n') break; + } + } + + fclose(fp); + + return TRUE; +} + +KMX_BOOL NamedCodeConstants::LoadFile(const KMX_CHAR *filename) +{ + const int buf_size = 260; + KMX_CHAR buf[buf_size]; + // Look in current directory first -- REMOVED AS DANGEROUS + /* strncpy(buf, filename, (buf_size-1)); buf[buf_size-1] = 0; // I3481 + if(kmcmp_FileExists(buf)) + return IntLoadFile(buf); + */ + // Then look in keyboard file directory (CompileDir) + strncpy(buf, CompileDir, (buf_size-1)); buf[buf_size-1] = 0; // I3481 + strncat(buf, filename, (buf_size-1)-strlen(CompileDir)); buf[buf_size-1] = 0; + if(kmcmp_FileExists(buf)) + return IntLoadFile(buf); + + //TODO: sort out how to find common includes in non-Windows platforms: + #ifdef _WINDOWS_ + // Finally look in kmcmpdll.dll directory + GetModuleFileName(0, buf, buf_size); + + KMX_CHAR *p = strrchr_slash(buf); + if(p) + p++; + else + p = buf; + *p = 0; + strncat_s(buf, _countof(buf), filename, (buf_size-1)-strlen(buf)); buf[buf_size-1] = 0; // I3481 // I3641 + if(kmcmp_FileExists(buf)) + return IntLoadFile(buf); + #endif + + reindex(); + + return FALSE; +} + +void NamedCodeConstants::reindex() +{ + if (entries != NULL) { + qsort(entries, nEntries, sizeof(NCCENTRY), sort_entries); + } + + KMX_WCHAR c = u'.', d; + int i; + + for(i = 0; i < 128; i++) chrindexes[i] = -1; + + if (entries != NULL) { + for (i = 0; i < nEntries; i++) + { + d = towupper(entries[i].name[0]); + if (d != c && d >= 32 && d <= 127) + chrindexes[c = d] = i; + } + } +} + +int NamedCodeConstants::GetCode(const KMX_WCHAR *codename, KMX_DWORD *storeIndex) +{ + *storeIndex = 0xFFFFFFFFL; // I2993 + int code = GetCode_IncludedCodes(codename); + if(code) return code; + for(int i = 0; i < nEntries_file; i++) { + if(!u16icmp(entries_file[i].name, codename)) { + *storeIndex = entries_file[i].storeIndex; + return entries_file[i].code; + } + } + return 0; +} + +int NamedCodeConstants::GetCode_IncludedCodes(const KMX_WCHAR *codename) +{ + KMX_WCHAR c = towupper(*codename); + int code; + + if(IsHangulSyllable(codename, &code)) return code; + + if(c < 32 || c > 127 || chrindexes[c] < 0) return 0; + for(int n = chrindexes[c]; n < nEntries && towupper(entries[n].name[0]) == c; n++) + { + int cmp = u16icmp(codename, entries[n].name); + if(cmp == 0) return entries[n].code; + if(cmp < 0) break; + } + return 0; +} + +/* + + Hangul Syllables + +*/ + +const int + HangulSBase = 0xAC00, + //HangulLBase = 0x1100, + //HangulVBase = 0x1161, + //HangulTBase = 0x11A7, + HangulLCount = 19, + HangulVCount = 21, + HangulTCount = 28; + //HangulNCount = HangulVCount * HangulTCount; // 588 + //HangulSCount = HangulLCount * HangulNCount; // 11172 + +const KMX_WCHAR * + Hangul_JAMO_L_TABLE[] = { + u"G", u"GG", u"N", u"D", u"DD", u"R", u"M", u"B", u"BB", + u"S", u"SS", u"", u"J", u"JJ", u"C", u"K", u"T", u"P", u"H" }; + +const KMX_WCHAR * + Hangul_JAMO_V_TABLE[] = { + u"A", u"AE", u"YA", u"YAE", u"EO", u"E", u"YEO", u"YE", u"O", + u"WA", u"WAE", u"OE", u"YO", u"U", u"WEO", u"WE", u"WI", + u"YU", u"EU", u"YI", u"I" }; + + +const KMX_WCHAR * + Hangul_JAMO_T_TABLE[] = { + u"", u"G", u"GG", u"GS", u"N", u"NJ", u"NH", u"D", u"u", u"LG", u"LM", + u"LB", u"LS", u"LT", u"LP", u"LH", u"M", u"B", u"BS", + u"S", u"SS", u"NG", u"J", u"C", u"K", u"T", u"P", u"H" }; + + +int IsHangulSyllable(const KMX_WCHAR *codename, int *code) +{ + if(u16nicmp(codename, u"HANGUL_SYLLABLE_", 16)) return 0; + codename += 16; + if(!*codename) return 0; + + int i, LIndex, VIndex, TIndex; + + /* Find initial */ + + int ch = towupper(*codename); + if(strchr("GNDRMBSJCKTPH", ch)) + { + /* Has an initial syllable */ + int isDoubled = towupper(*(codename+1)) == ch; + + LIndex = -1; + for(i = 0; i < HangulLCount; i++) { + if(Hangul_JAMO_L_TABLE[i][0] == ch && (!isDoubled || (Hangul_JAMO_L_TABLE[i][1] == ch && isDoubled))) { + LIndex = i; + break; + } + } + if(LIndex == -1) return 0; + codename++; + if(isDoubled) codename++; + } + else LIndex = 11; /* no initial */ + + /* Find vowel */ + + KMX_WCHAR V[4] = u""; + V[0] = *codename; + if(V[0] && strchr("AEIOUWY", towupper(*(codename+1)))) V[1] = *(codename+1); + if(V[1] && strchr("AEIOUWY", towupper(*(codename+2)))) V[2] = *(codename+2); + + VIndex = -1; + for(i = 0; i < HangulVCount; i++) { + if(!u16icmp(Hangul_JAMO_V_TABLE[i], V)) { + VIndex = i; + break; + } + } + + if(VIndex == -1) return 0; + + codename += u16len(V); + + /* Find final */ + + TIndex = -1; + + for(i = 0; i < HangulTCount; i++) { + if(!u16icmp(Hangul_JAMO_T_TABLE[i], codename)) { + TIndex = i; + break; + } + } + + if(TIndex == -1) return 0; + + /* Composition */ + + *code = (HangulSBase + (LIndex * HangulVCount + VIndex) * HangulTCount) + TIndex; + + return 1; +} diff --git a/developer/src/kmcmplib/src/NamedCodeConstants.h b/developer/src/kmcmplib/src/NamedCodeConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..83d707d092cc4535a24cf3676aaa3d2a44d7b859 --- /dev/null +++ b/developer/src/kmcmplib/src/NamedCodeConstants.h @@ -0,0 +1,37 @@ + +#ifndef NAMEDCODECONSTANTS_H +#define NAMEDCODECONSTANTS_H + +#define MAX_ENAME 128 +#define ALLOC_SIZE 256 + +struct NCCENTRY +{ + KMX_WCHAR name[MAX_ENAME+1]; + int code; + KMX_DWORD storeIndex; +}; + +namespace kmcmp{ + class NamedCodeConstants + { + private: + NCCENTRY *entries; // entries from &includecodes + NCCENTRY *entries_file; // entries from store(myconst) x + int nEntries, nEntries_file; + int chrindexes[128]; // A-Z, 0-9, -, _; simple index + + int GetCode_IncludedCodes(const KMX_WCHAR *codename); + void AddCode_IncludedCodes(int n, const KMX_WCHAR *p); + KMX_BOOL IntLoadFile(const KMX_CHAR *filename); + public: + NamedCodeConstants(); + ~NamedCodeConstants(); + + void reindex(); + void AddCode(int n, const KMX_WCHAR *p, KMX_DWORD storeIndex); + KMX_BOOL LoadFile(const KMX_CHAR *filename); + int GetCode(const KMX_WCHAR *codename, KMX_DWORD *storeIndex); + }; +} +#endif //NAMEDCODECONSTANTS_H diff --git a/developer/src/kmcmplib/src/UnreachableRules.cpp b/developer/src/kmcmplib/src/UnreachableRules.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f7a9b4a5feb049a85946ef7cf57cc06ff42c163b --- /dev/null +++ b/developer/src/kmcmplib/src/UnreachableRules.cpp @@ -0,0 +1,57 @@ + +#include "pch.h" + +#include "compfile.h" +#include +#include "../../../../common/windows/cpp/include/vkeys.h" +#include "kmcmplib.h" + +#include +#include +#include +#include + +#include "UnreachableRules.h" + +namespace kmcmp { + std::wstring MakeHashKeyFromFileKey(PFILE_KEY kp) { + std::wstringstream key; + key << kp->Key << "," << kp->ShiftFlags << ","; + if (kp->dpContext) { + std::wstring Context_ws = u16fmt((const PKMX_WCHAR) kp->dpContext); + key << Context_ws; + } + return key.str(); + } + +} +KMX_DWORD VerifyUnreachableRules(PFILE_GROUP gp) { + PFILE_KEY kp = gp->dpKeyArray; + KMX_DWORD i; + + int oldCurrentLine = kmcmp::currentLine; + + std::unordered_map map; + std::unordered_set reportedLines; + + for (i = 0; i < gp->cxKeyArray; i++, kp++) { + std::wstring key = kmcmp::MakeHashKeyFromFileKey(kp); + if (map.count(key) > 0) { + FILE_KEY const & k1 = map.at(key); + if (kp->Line != k1.Line && reportedLines.count(kp->Line) == 0) { + reportedLines.insert(kp->Line); + kmcmp::currentLine = kp->Line; + u16sprintf(ErrExtraW, 256, L" Overridden by rule on line %d", k1.Line); + strcpy(ErrExtraLIB, string_from_u16string(ErrExtraW).c_str()); + AddWarning(CHINT_UnreachableRule); + } + } + else { + map.insert({ key, *kp }); + } + } + + kmcmp::currentLine = oldCurrentLine; + + return CERR_None; +} diff --git a/developer/src/kmcmplib/src/UnreachableRules.h b/developer/src/kmcmplib/src/UnreachableRules.h new file mode 100644 index 0000000000000000000000000000000000000000..d9eac65ce3cbec70fa2a88795db96fd28e0e6bf0 --- /dev/null +++ b/developer/src/kmcmplib/src/UnreachableRules.h @@ -0,0 +1,3 @@ +#pragma once + +KMX_DWORD VerifyUnreachableRules(PFILE_GROUP gp); diff --git a/developer/src/kmcmplib/src/comperr.h b/developer/src/kmcmplib/src/comperr.h new file mode 100644 index 0000000000000000000000000000000000000000..3d1658af0ed8c99ee03e5c147cf9f4c6134ba3f2 --- /dev/null +++ b/developer/src/kmcmplib/src/comperr.h @@ -0,0 +1,233 @@ +/* + Name: Comperr + Copyright: Copyright (C) SIL International. + Documentation: + Description: + Create Date: 23 Aug 2006 + + Modified Date: 6 Mar 2014 + Authors: mcdurdin + Related Files: + Dependencies: + + Bugs: + Todo: + Notes: + History: 23 Aug 2006 - mcdurdin - Add Keyman 7.0 feature error + 25 May 2010 - mcdurdin - I1632 - Keyboard Options + 21 Feb 2014 - mcdurdin - I4061 - V9.0 - KeymanWeb compiler needs defined codes for some errors + 06 Mar 2014 - mcdurdin - I4118 - V9.0 - KMW compiler should warn when extended shift flags are used + 22 Jul 2020 - eddieantonio - Add lexical model range https://github.com/keymanapp/keyman/pull/3385 +*/ + // I4061 +#ifndef _COMPERR_H +#define _COMPERR_H + +// Note: these are not be a bitmask +#define CERR_FATAL 0x00008000 +#define CERR_ERROR 0x00004000 +#define CERR_WARNING 0x00002000 +#define CERR_HINT 0x00001000 + +// Any messages from the lexical model compiler occupy this range: +#define CERR_LEXICAL_MODEL_MIN 0x00000800 +#define CERR_LEXICAL_MODEL_MAX 0x000008FF + +#define CERR_None 0x00000000 +#define CERR_EndOfFile 0x00000001 + +#define CERR_BadCallParams 0x00008002 +#define CERR_CannotAllocateMemory 0x00008004 +#define CERR_InfileNotExist 0x00008005 +#define CERR_CannotCreateOutfile 0x00008006 +#define CERR_UnableToWriteFully 0x00008007 +#define CERR_CannotReadInfile 0x00008008 +#define CERR_SomewhereIGotItWrong 0x00008009 + +#define CERR_InvalidToken 0x0000400A +#define CERR_InvalidBegin 0x0000400B +#define CERR_InvalidName 0x0000400C +#define CERR_InvalidVersion 0x0000400D +#define CERR_InvalidLanguageLine 0x0000400E +#define CERR_LayoutButNoLanguage 0x0000400F +#define CERR_InvalidLayoutLine 0x00004010 +#define CERR_NoVersionLine 0x00004011 +#define CERR_InvalidGroupLine 0x00004012 +#define CERR_InvalidStoreLine 0x00004013 +#define CERR_InvalidCodeInKeyPartOfRule 0x00004014 +#define CERR_InvalidDeadkey 0x00004015 +#define CERR_InvalidValue 0x00004016 +#define CERR_ZeroLengthString 0x00004017 +#define CERR_TooManyIndexToKeyRefs 0x00004018 +#define CERR_UnterminatedString 0x00004019 +#define CERR_StringInVirtualKeySection 0x0000401A +#define CERR_AnyInVirtualKeySection 0x0000401B +#define CERR_InvalidAny 0x0000401C +#define CERR_StoreDoesNotExist 0x0000401D +#define CERR_BeepInVirtualKeySection 0x0000401E +#define CERR_IndexInVirtualKeySection 0x0000401F +#define CERR_InvalidIndex 0x00004020 +#define CERR_OutsInVirtualKeySection 0x00004021 +#define CERR_InvalidOuts 0x00004022 +#define CERR_ContextInVirtualKeySection 0x00004024 +#define CERR_InvalidUse 0x00004025 +#define CERR_GroupDoesNotExist 0x00004026 +#define CERR_VirtualKeyNotAllowedHere 0x00004027 +#define CERR_InvalidSwitch 0x00004028 +#define CERR_NoTokensFound 0x00004029 +#define CERR_InvalidLineContinuation 0x0000402A +#define CERR_LineTooLong 0x0000402B +#define CERR_InvalidCopyright 0x0000402C +#define CERR_CodeInvalidInThisSection 0x0000402D +#define CERR_InvalidMessage 0x0000402E +#define CERR_InvalidLanguageName 0x0000402F +#define CERR_InvalidBitmapLine 0x00004030 +#define CERR_CannotReadBitmapFile 0x00004031 +#define CERR_IndexDoesNotPointToAny 0x00004032 +#define CERR_ReservedCharacter 0x00004033 +#define CERR_InvalidCharacter 0x00004034 +#define CERR_InvalidCall 0x00004035 +#define CERR_CallInVirtualKeySection 0x00004036 +#define CERR_CodeInvalidInKeyStore 0x00004037 +#define CERR_CannotLoadIncludeFile 0x00004038 + +#define CERR_60FeatureOnly_EthnologueCode 0x00004039 +#define CERR_60FeatureOnly_MnemonicLayout 0x0000403A +#define CERR_60FeatureOnly_OldCharPosMatching 0x0000403B +#define CERR_60FeatureOnly_NamedCodes 0x0000403C +#define CERR_60FeatureOnly_Contextn 0x0000403D +#define CERR_501FeatureOnly_Call 0x0000403E + +#define CERR_InvalidNamedCode 0x0000403F +#define CERR_InvalidSystemStore 0x00004040 + +#define CERR_60FeatureOnly_VirtualCharKey 0x00004044 + +#define CERR_VersionAlreadyIncluded 0x00004045 + +#define CERR_70FeatureOnly 0x00004046 + +#define CERR_80FeatureOnly 0x00004047 +#define CERR_InvalidInVirtualKeySection 0x00004048 +#define CERR_InvalidIf 0x00004049 +#define CERR_InvalidReset 0x0000404A +#define CERR_InvalidSet 0x0000404B +#define CERR_InvalidSave 0x0000404C + +#define CERR_InvalidEthnologueCode 0x0000404D + +#define CERR_CannotCreateTempfile 0x0000804E + +#define CERR_90FeatureOnly_IfSystemStores 0x0000404F +#define CERR_IfSystemStore_NotFound 0x00004050 +#define CERR_90FeatureOnly_SetSystemStores 0x00004051 +#define CERR_SetSystemStore_NotFound 0x00004052 +#define CERR_90FeatureOnlyVirtualKeyDictionary 0x00004053 + +#define CERR_NotSupportedInKeymanWebContext 0x00004054 +#define CERR_NotSupportedInKeymanWebOutput 0x00004055 +#define CERR_NotSupportedInKeymanWebStore 0x00004056 +#define CERR_VirtualCharacterKeysNotSupportedInKeymanWeb 0x00004057 +#define CERR_VirtualKeysNotValidForMnemonicLayouts 0x00004058 +#define CERR_InvalidTouchLayoutFile 0x00004059 +#define CERR_TouchLayoutInvalidIdentifier 0x0000405A +#define CERR_InvalidKeyCode 0x0000405B +#define CERR_90FeatureOnlyLayoutFile 0x0000405C +#define CERR_90FeatureOnlyKeyboardVersion 0x0000405D +#define CERR_KeyboardVersionFormatInvalid 0x0000405E +#define CERR_ContextExHasInvalidOffset 0x0000405F +#define CERR_90FeatureOnlyEmbedCSS 0x00004060 +#define CERR_90FeatureOnlyTargets 0x00004061 +#define CERR_ContextAndIndexInvalidInMatchNomatch 0x00004062 +#define CERR_140FeatureOnlyContextAndNotAnyWeb 0x00004063 + +#define CERR_ExpansionMustFollowCharacterOrVKey 0x00004064 +#define CERR_VKeyExpansionMustBeFollowedByVKey 0x00004065 +#define CERR_CharacterExpansionMustBeFollowedByCharacter 0x00004066 +#define CERR_VKeyExpansionMustUseConsistentShift 0x00004067 +#define CERR_ExpansionMustBePositive 0x00004068 + +#define CERR_CasedKeysMustContainOnlyVirtualKeys 0x00004069 +#define CERR_CasedKeysMustNotIncludeShiftStates 0x0000406A +#define CERR_CasedKeysNotSupportedWithMnemonicLayout 0x0000406B + +#define CERR_CannotUseReadWriteGroupFromReadonlyGroup 0x0000406C +#define CERR_StatementNotPermittedInReadonlyGroup 0x0000406D +#define CERR_OutputInReadonlyGroup 0x0000406E +#define CERR_NewContextGroupMustBeReadonly 0x0000406F +#define CERR_PostKeystrokeGroupMustBeReadonly 0x00004070 + +#define CERR_DuplicateGroup 0x00004071 +#define CERR_DuplicateStore 0x00004072 + +#define CERR_RepeatedBegin 0x00004073 + +#define CWARN_TooManyWarnings 0x00002080 +#define CWARN_OldVersion 0x00002081 +#define CWARN_BitmapNotUsed 0x00002082 +#define CWARN_CustomLanguagesNotSupported 0x00002083 +#define CWARN_KeyBadLength 0x00002084 +#define CWARN_IndexStoreShort 0x00002085 +#define CWARN_UnicodeInANSIGroup 0x00002086 +#define CWARN_ANSIInUnicodeGroup 0x00002087 +#define CWARN_UnicodeSurrogateUsed 0x00002088 +#define CWARN_ReservedCharacter 0x00002089 +#define CWARN_Info 0x0000208A +#define CWARN_VirtualKeyWithMnemonicLayout 0x0000208B +#define CWARN_VirtualCharKeyWithPositionalLayout 0x0000208C +#define CWARN_StoreAlreadyUsedAsOptionOrCall 0x0000208D +#define CWARN_StoreAlreadyUsedAsStoreOrCall 0x0000208E +#define CWARN_StoreAlreadyUsedAsStoreOrOption 0x0000208F + +#define CWARN_PunctuationInEthnologueCode 0x00002090 + +#define CWARN_TouchLayoutMissingLayer 0x00002091 +#define CWARN_TouchLayoutCustomKeyNotDefined 0x00002092 +#define CWARN_TouchLayoutMissingRequiredKeys 0x00002093 +#define CWARN_HelpFileMissing 0x00002094 +#define CWARN_EmbedJsFileMissing 0x00002095 +#define CWARN_TouchLayoutFileMissing 0x00002096 +#define CWARN_VisualKeyboardFileMissing 0x00002097 +#define CWARN_ExtendedShiftFlagsNotSupportedInKeymanWeb 0x00002098 // I4118 +#define CWARN_TouchLayoutUnidentifiedKey 0x00002099 +#define CHINT_UnreachableKeyCode 0x0000109A + +#define CWARN_CouldNotCopyJsonFile 0x0000209B +#define CWARN_PlatformNotInTargets 0x0000209C + +#define CWARN_HeaderStatementIsDeprecated 0x0000209D +#define CWARN_UseNotLastStatementInRule 0x0000209E + +#define CWARN_TouchLayoutFontShouldBeSameForAllPlatforms 0x0000209F +#define CWARN_InvalidJSONMetadataFile 0x000020A0 +#define CWARN_JSONMetadataOSKFontShouldMatchTouchFont 0x000020A1 +#define CWARN_KVKFileIsInSourceFormat 0x000020A2 + +#define CWARN_DontMixChiralAndNonChiralModifiers 0x000020A3 +#define CWARN_MixingLeftAndRightModifiers 0x000020A4 + +#define CWARN_LanguageHeadersDeprecatedInKeyman10 0x000020A5 + +#define CHINT_NonUnicodeFile 0x000010A6 + +#define CWARN_TooManyErrorsOrWarnings 0x000020A7 + +#define CWARN_HotkeyHasInvalidModifier 0x000020A8 + +#define CWARN_TouchLayoutSpecialLabelOnNormalKey 0x000020A9 + +#define CWARN_OptionStoreNameInvalid 0x000020AA + +#define CWARN_NulNotFirstStatementInContext 0x000020AB +#define CWARN_IfShouldBeAtStartOfContext 0x000020AC + +#define CWARN_KeyShouldIncludeNCaps 0x000020AD + +#define CHINT_UnreachableRule 0x000010AE +#define CHINT_FilenameHasDifferingCase 0x000010AF +#define CWARN_MissingFile 0x000020B0 + +#define CERR_BufferOverflow 0x000080C0 +#define CERR_Break 0x000080C1 + +#endif // _COMPERR_H diff --git a/developer/src/kmcmplib/src/compfile.h b/developer/src/kmcmplib/src/compfile.h new file mode 100644 index 0000000000000000000000000000000000000000..48be5f20482f444dde7ec9b516b835b1d15ba77e --- /dev/null +++ b/developer/src/kmcmplib/src/compfile.h @@ -0,0 +1,220 @@ +/* + Name: Compfile + Copyright: Copyright (C) SIL International. + Documentation: + Description: + Create Date: 25 Jan 2007 + + Modified Date: 25 May 2010 + Authors: mcdurdin + Related Files: + Dependencies: + + Bugs: + Todo: + Notes: + History: 25 Jan 2007 - mcdurdin - Add GLOBAL_BUFSIZE, enlarge LINESIZE + 25 May 2010 - mcdurdin - I1632 - Keyboard Options +*/ + +#ifndef _COMPFILE_H +#define _COMPFILE_H + +#include "kmcompx.h" +#include + +#define LINESIZE 8192 +#define GLOBAL_BUFSIZE 4096 + +#define SZMAX_STORENAME 80 +#define SZMAX_GROUPNAME 80 +#define SZMAX_DEADKEYNAME 80 +#define SZMAX_ERRORTEXT 512 +#define SZMAX_VKDICTIONARYNAME 80 + +#define MAX_WARNINGS 100 + +#define T_COMMENT 1 // A comment line +#define T_KEYTOKEY 2 // A rule line +#define T_BLANK 3 // A blank line + +#define T_W_START 4 // Start of easily matched line types +#define T_STORE 4 // A store line +#define T_VERSION 5 // A 'VERSION 3.2/3.1/3.0' line +#define T_NAME 6 // A 'NAME "xxxx"' line +#define T_BITMAP 7 // A 'BITMAP bmpfile' line +#define T_HOTKEY 8 // A 'HOTKEY "^%+C"' line +#define T_BEGIN 9 // A 'begin > use(xxxx)' line +#define T_GROUP 10 // A 'group(xxxx)' line +#define T_MATCH 11 // A 'match > "XXXX"' line +#define T_NOMATCH 12 // A 'nomatch > "XXXX"' line +#define T_SHIFT 13 // A 'SHIFT FREES CAPS' line +#define T_CAPSON 14 // A 'CAPS ON ONLY' line +#define T_CAPSOFF 15 // A 'CAPS ALWAYS OFF' line +#define T_LANGUAGE 16 // A 'LANGUAGE xxxh, xxh' line +#define T_LAYOUT 17 // A 'LAYOUT xxxxh' line +#define T_COPYRIGHT 18 // A 'COPYRIGHT "so and so"' line +#define T_MESSAGE 19 // A 'MESSAGE "so and so"' line +#define T_LANGUAGENAME 20 // A 'LANGUAGENAME "xxxx"' line +#define T_BITMAPS 21 // An unused 'BITMAPS' line (version 3.x) +#define T_W_END 21 // End of easily matched rule types + +#define T_UNKNOWN 99 // Unrecognized line type (illegal line) + +#define GDS_CUTLEAD 0x01 // GetDelimitedString: cut leading spaces +#define GDS_CUTFOLL 0x02 // GetDelimitedString: cut following spaces + +#define GXS_LINE 0x00 // GetExtendedString error: in a "line" +#define GXS_RULE 0x01 // GetExtendedString error: in a "rule" +#define GXS_STORE 0x02 // GetExtendedString error: in a "store" + +enum FileStoreType { FST_STORE, FST_OPTION, FST_RESERVED }; + +struct FILE_STORE { + KMX_DWORD dwSystemID; + KMX_WCHAR szName[SZMAX_STORENAME]; // the name of the store + PKMX_WCHAR dpString; // from start of store structure + //FileStoreType fstType; + KMX_BOOL fIsStore; + KMX_BOOL fIsReserved; + KMX_BOOL fIsOption; + KMX_BOOL fIsDebug; + KMX_BOOL fIsCall; + int line; + }; + +typedef FILE_STORE * PFILE_STORE; + + +struct FILE_KEY { + KMX_WCHAR Key; // WCHAR for consistency; only a byte used however + KMX_WORD LineStoreIndex; + KMX_DWORD Line; + KMX_DWORD ShiftFlags; + PKMX_WCHAR dpOutput; // from start of key structure + PKMX_WCHAR dpContext; // from start of key structure + }; +typedef FILE_KEY *PFILE_KEY; + + +struct FILE_GROUP { + KMX_WCHAR szName[SZMAX_GROUPNAME]; + PFILE_KEY dpKeyArray; // address of first item in key array, from start of group structure + PKMX_WCHAR dpMatch; // from start of group structure + PKMX_WCHAR dpNoMatch; // from start of group structure + KMX_DWORD cxKeyArray; // in array items + KMX_BOOL fUsingKeys; // group(xx) [using keys] <-- specified or not + KMX_BOOL fReadOnly; // group(xx) [readonly] <-- specified or not + KMX_DWORD Line; + }; +typedef FILE_GROUP *PFILE_GROUP; + +struct FILE_DEADKEY +{ + KMX_WCHAR szName[SZMAX_DEADKEYNAME]; +}; +typedef FILE_DEADKEY *PFILE_DEADKEY; + +struct FILE_VKDICTIONARY +{ + KMX_WCHAR szName[SZMAX_VKDICTIONARYNAME]; +}; +typedef FILE_VKDICTIONARY *PFILE_VKDICTIONARY; + +struct FILE_KEYBOARD { + KMX_DWORD KeyboardID; // as stored in HKEY_LOCAL_MACHINE//system//currentcontrolset//control//keyboard layouts + + KMX_DWORD version; // keyboard file version with VERSION keyword + + PFILE_STORE dpStoreArray; // address of first item in store array, from start of store structure + PFILE_GROUP dpGroupArray; // address of first item in group array, from start of group structure + + KMX_DWORD cxStoreArray; // in number of items + KMX_DWORD cxGroupArray; // in number of items + KMX_DWORD StartGroup[2]; // index of starting groups [ANSI=0, Unicode=1] + + KMX_DWORD dwHotKey; // standard windows hotkey (hiword=shift/ctrl/alt stuff, loword=vkey) + + KMX_WCHAR szName[SZMAX_KEYBOARDNAME]; // Keyboard layout name + KMX_WCHAR szLanguageName[SZMAX_LANGUAGENAME]; // Language name + KMX_WCHAR szCopyright[SZMAX_COPYRIGHT]; // Copyright information + KMX_WCHAR szMessage[SZMAX_MESSAGE]; // General information about the keyboard + PKMX_BYTE lpBitmap; + KMX_DWORD dwBitmapSize; + KMX_DWORD dwFlags; // Flags for the keyboard file + + KMX_DWORD currentGroup; // temp - current processing group + KMX_DWORD currentStore; // temp - current processing store + KMX_DWORD cxDeadKeyArray; + PFILE_DEADKEY dpDeadKeyArray; // temp - dead key array + KMX_DWORD cxVKDictionary; + PFILE_VKDICTIONARY dpVKDictionary; // temp - virtual key dictionary + }; + +typedef FILE_KEYBOARD *PFILE_KEYBOARD; + +/* +These size values are used in unit tests to ensure +that the structure sizes correspond precisely across +compilers (pas and c++). +*/ + +const KMX_DWORD sz_FILE_STORE = sizeof(FILE_STORE); +const KMX_DWORD sz_FILE_KEY = sizeof(FILE_KEY); +const KMX_DWORD sz_FILE_GROUP = sizeof(FILE_GROUP); +const KMX_DWORD sz_FILE_DEADKEY = sizeof(FILE_DEADKEY); +const KMX_DWORD sz_FILE_VKDICTIONARY = sizeof(FILE_VKDICTIONARY); +const KMX_DWORD sz_FILE_KEYBOARD = sizeof(FILE_KEYBOARD); + +struct COMPMSG { + KMX_CHAR szText[SZMAX_ERRORTEXT]; + KMX_DWORD Line; + KMX_DWORD dwMsgCode; + }; + +typedef COMPMSG *PCOMPMSG; + +struct COMPILEMESSAGES { + int nMessages; + int nErrors; + + PCOMPMSG cm; + + KMX_DWORD fatalCode; + KMX_CHAR szFatalText[SZMAX_ERRORTEXT]; + + KMX_DWORD currentLine; + }; + +typedef COMPILEMESSAGES *PCOMPILEMESSAGES; + +/* +struct TVersion +{ + //int MinVersion; // 0x0500 usually + //int CompilerVersion[4]; + //int MinCompilerVersion[4]; + int KeyboardVersion; // 0x0500 usually +}; + +extern TVersion FVersionInfo; +*/ + +/* +#define bstrcpy(c,d) (LPBYTE)strcpy((LPSTR)(c),(LPSTR)(d)) +#define bstrlen(c) strlen((LPSTR)(c)) +#define bstrcmp(c,d) strcmp((LPSTR)(c),(LPSTR)(d)) +#define bstrncmp(c,d,n) strncmp((LPSTR)(c),(LPSTR)(d),(n)) +#define bstrnicmp(c,d,n) strnicmp((LPSTR)(c),(LPSTR)(d),(n)) +#define bstricmp(c,d) stricmp((LPSTR)(c),(LPSTR)(d)) +#define bstrchr(c,ch) (LPBYTE)strchr((LPSTR)(c),(char)ch) +#define bstrncpy(c,d,n) (LPBYTE)strncpy((LPSTR)(c),(LPSTR)(d),(n)) +#define bstrtok(c,d) (LPBYTE)strtok((LPSTR)(c),(LPSTR)(d)) +#define bstrcat(c,d) (LPBYTE)strcat((LPSTR)(c),(LPSTR)(d)) +#define bstrncat(c,d,n) (LPBYTE)strncat((LPSTR)(c),(LPSTR)(d),(n)) +#define bstrrev(c) (LPBYTE)strrev((LPSTR)(c)) +#define batoi(c) atoi((LPSTR)(c)) +#define bstrtol(c,d,n) strtol((LPSTR)(c),(LPSTR *)(d),(n)) +*/ + +#endif // _COMPFILE_H diff --git a/developer/src/kmcmplib/src/debugstore.h b/developer/src/kmcmplib/src/debugstore.h new file mode 100644 index 0000000000000000000000000000000000000000..c54e3b45c343cb1eb3fdf006134253d706c8d915 --- /dev/null +++ b/developer/src/kmcmplib/src/debugstore.h @@ -0,0 +1,20 @@ + +#ifndef DEBUGSTORE_H +#define DEBUGSTORE_H + +#define DEBUGSTORE_BEGIN u"B" +#define DEBUGSTORE_BEGIN_C u'B' + +#define DEBUGSTORE_MATCH u"M" +#define DEBUGSTORE_MATCH_C u'M' + +#define DEBUGSTORE_NOMATCH u"N" +#define DEBUGSTORE_NOMATCH_C u'N' + +#define DEBUGSTORE_GROUP u"G" +#define DEBUGSTORE_GROUP_C u'G' + +#define DEBUGSTORE_DEADKEY u"D" +#define DEBUGSTORE_DEADKEY_C u'D' + +#endif /* DEBUGSTORE_H */ diff --git a/developer/src/kmcmplib/src/filesystem.cpp b/developer/src/kmcmplib/src/filesystem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a343641acc128ed5537e0e1835d45a2253c29f2e --- /dev/null +++ b/developer/src/kmcmplib/src/filesystem.cpp @@ -0,0 +1,188 @@ + +#ifdef __EMSCRIPTEN__ +#include +#include +#endif + +#include +#include +#include +#include "filesystem.h" + +#ifdef _MSC_VER +#include +#else +#include +#endif + +//#define _DEBUG_FOPEN 1 + +#ifdef __EMSCRIPTEN__ + +const std::string get_wasm_file_path(const std::string& filename) { + // Verify that we are passing a fully-qualified path + // TODO: we need to support relative paths based on CWD +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path ENTER (" << filename << ")" << std::endl; +#endif + + assert( + (filename.length() > 0 && filename.at(0) == '/') || + (filename.length() > 1 && filename.at(1) == ':') + ); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path assert passed " << std::endl; +#endif + + EM_ASM_({ + //console.log('EM_ASM enter'); + let path = Module.UTF8ToString($0); + const isWin32Path = path.match(/^[a-zA-Z]:/); + + //console.log('EM_ASM path = '+path); + let root = '/nodefs-mount'; + if(!FS.analyzePath(root).exists) { + //console.log('EM_ASM mkdir '+root); + FS.mkdir(root); + if(!isWin32Path) { + //console.log('EM_ASM mount '+root); + FS.mount(NODEFS, {root : '/'}, root); + } + } + + if(isWin32Path) { + // Win32 path, one mount per drive + root += "/" + path.charAt(0); + if(!FS.analyzePath(root).exists) { + //console.log('EM_ASM mkdir '+root); + FS.mkdir(root); + //console.log('EM_ASM mount '+root); + FS.mount(NODEFS, {root : path.substr(0,3) }, root); + } + } + }, filename.c_str()); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path EM_ASM_ passed " << std::endl; +#endif + + std::string f = std::string("/nodefs-mount"); + + if(filename.length() > 2 && filename.at(1) == ':') { + f += std::string("/") + filename.at(0) + filename.substr(2); + } else { + f += filename; + } + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path opening virtual path: " << f << std::endl; +#endif + + return f; +} + +FILE* fopen_wasm(const std::string& filename, const std::string& mode) { + std::string f = get_wasm_file_path(filename); + FILE* fp = fopen(f.c_str(), mode.c_str()); + +#if _DEBUG_FOPEN + std::cout << "get_wasm_file_path fopen called, returned " << fp << std::endl; +#endif + + return fp; +} + +#endif + +#ifndef _MSC_VER +#ifdef __EMSCRIPTEN__ +#define fopen_wrapper fopen_wasm +#else +#define fopen_wrapper fopen +#endif +#endif + +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode) { +#ifdef _MSC_VER + std::string cpath = Filename; //, cmode = mode; + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return fopen(cpath.c_str(), (const KMX_CHAR*) mode); +#else + return fopen_wrapper(Filename, mode); + std::string cpath, cmode; + cpath = (const KMX_CHAR*) Filename; + cmode = (const KMX_CHAR*) mode; + return fopen_wrapper(cpath.c_str(), cmode.c_str()); +#endif +}; + +FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode) { +#ifdef _MSC_VER + std::wstring cpath = Filename; //, cmode = mode; + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return _wfsopen(cpath.c_str(), mode, _SH_DENYWR); +#else + std::string cpath, cmode; + cpath = string_from_wstring(Filename); + cmode = string_from_wstring(mode); + return fopen_wrapper(cpath.c_str(), cmode.c_str()); +#endif +}; + +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode) { +#ifdef _MSC_VER + std::wstring cpath = convert_pchar16T_To_wstr((KMX_WCHAR*) Filename); + std::wstring cmode = convert_pchar16T_To_wstr((KMX_WCHAR*) mode); + std::replace(cpath.begin(), cpath.end(), '/', '\\'); + return _wfsopen(cpath.c_str(), cmode.c_str(), _SH_DENYWR); +#else + std::string cpath, cmode; + cpath = string_from_u16string(Filename); + cmode = string_from_u16string(mode); + return fopen_wrapper(cpath.c_str(), cmode.c_str()); +#endif +}; + +KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename) { + +#ifdef _MSC_VER + intptr_t n; + _finddata_t fi; + if((n = _findfirst(filename, &fi)) != -1) { + _findclose(n); + return TRUE; + } +#else //!_MSC_VER + +#ifdef __EMSCRIPTEN__ + std::string f = get_wasm_file_path(filename); +#else //!__EMSCRIPTEN__ + std::string f = filename; +#endif // !__EMSCRIPTEN__ + + if(access(f.c_str(), F_OK) != -1) { + return TRUE; + } + +#endif // !_MSC_VER + + return FALSE; +} + +KMX_BOOL kmcmp_FileExists(const KMX_WCHAR* filename) { +#ifdef _MSC_VER + intptr_t n; + _wfinddata_t fi; + if((n = _wfindfirst((wchar_t*) filename, &fi)) != -1) { + _findclose(n); + return TRUE; + } +#else + std::string cpath; + cpath = string_from_u16string(filename); + return kmcmp_FileExists(cpath.c_str()); +#endif + + return FALSE; +}; diff --git a/developer/src/kmcmplib/src/filesystem.h b/developer/src/kmcmplib/src/filesystem.h new file mode 100644 index 0000000000000000000000000000000000000000..786b7268ac0c09bdda634296445e7e448404cc1e --- /dev/null +++ b/developer/src/kmcmplib/src/filesystem.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include "kmx_u16.h" + +// Opens files on windows and non-windows platforms. Datatypes for Filename and mode must be the same. +// returns FILE* if file could be opened; FILE needs to be closed in calling function +FILE* Open_File(const KMX_CHAR* Filename, const KMX_CHAR* mode); +FILE* Open_File(const KMX_WCHART* Filename, const KMX_WCHART* mode); +FILE* Open_File(const KMX_WCHAR* Filename, const KMX_WCHAR* mode); +KMX_BOOL kmcmp_FileExists(const KMX_CHAR *filename); +KMX_BOOL kmcmp_FileExists(const KMX_WCHAR *filename); diff --git a/developer/src/kmcmplib/src/json-validation.cpp b/developer/src/kmcmplib/src/json-validation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f58d8c950534943427285a4f400fb39c190217ff --- /dev/null +++ b/developer/src/kmcmplib/src/json-validation.cpp @@ -0,0 +1,68 @@ + +#include +#include + +#include +#include "kmcompx.h" + +using nlohmann::json; +using nlohmann::json_uri; +using nlohmann::json_schema_draft4::json_validator; + +static void loader(const json_uri &uri, json &schema) +{ + std::fstream lf("." + uri.path()); + if (!lf.good()) + throw std::invalid_argument("could not open " + uri.url() + " tried with " + uri.path()); + + lf >> schema; +} + +EXTERN bool kmcmp_ValidateJsonFile(std::fstream& f, std::fstream& fd, kmcmp_ValidateJsonMessageProc MessageProc, void* context) { + if (!f.good()) { + MessageProc(-1, "Schema file could not be loaded.", context); + return FALSE; + } + + // 1) Read the schema for the document you want to validate + json schema; + try { + f >> schema; + } + catch (std::exception &e) { + MessageProc(f.tellp(), e.what(), context); + return FALSE; + } + + // 2) create the validator and + json_validator validator(loader, [](const std::string &, const std::string &) {}); + + try { + // insert this schema as the root to the validator + // this resolves remote-schemas, sub-schemas and references via the given loader-function + validator.set_root_schema(schema); + } + catch (std::exception &e) { + MessageProc(-2, e.what(), context); + return FALSE; + } + + // 3) do the actual validation of the document + json document; + + if (!fd.good()) { + MessageProc(-3, "Json file could not be loaded.", context); + return FALSE; + } + + try { + fd >> document; + validator.validate(document); + } + catch (std::exception &e) { + MessageProc(fd.tellp(), e.what(), context); + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/developer/src/kmcmplib/src/kmcmplib.h b/developer/src/kmcmplib/src/kmcmplib.h new file mode 100644 index 0000000000000000000000000000000000000000..13d871f0ec634c0589eaeefd7b8acb26af63bc72 --- /dev/null +++ b/developer/src/kmcmplib/src/kmcmplib.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include "compfile.h" +#include "NamedCodeConstants.h" + +namespace kmcmp { + KMX_BOOL AddCompileWarning(char* buf); + extern int currentLine; + extern KMX_BOOL FShouldAddCompilerVersion; + extern KMX_BOOL FSaveDebug, FCompilerWarningsAsErrors; // I4865 // I4866 + extern int ErrChr; + extern int nErrors; + extern KMX_BOOL FMnemonicLayout; + extern KMX_BOOL FOldCharPosMatching; + extern int CompileTarget; + extern KMX_CHAR CompileDir[260]; // TODO: this should not be a fixed buffer + extern int BeginLine[4]; + extern int currentLine; + extern NamedCodeConstants *CodeConstants; + + void RecordDeadkeyNames(PFILE_KEYBOARD fk); + KMX_DWORD AddCompilerVersionStore(PFILE_KEYBOARD fk); +} + +extern kmcmp_CompilerMessageProc msgproc; +extern void* msgprocContext; + +extern KMX_BOOL AWarnDeprecatedCode_GLOBAL_LIB; +extern char ErrExtraLIB[256]; +extern KMX_WCHAR ErrExtraW[256]; +KMX_BOOL AddCompileError(KMX_DWORD msg); + +/// Use AddWarningBool for functions that return bool or KMX_BOOL +#define AddWarningBool(warn) { if(AddCompileError(warn)) return FALSE; } +/// Use AddWarning for functions that return KMX_DWORD +#define AddWarning(warn) { if(AddCompileError(warn)) return CERR_Break; } + +PKMX_WCHAR strtowstr(PKMX_STR in); +PFILE_STORE FindSystemStore(PFILE_KEYBOARD fk, KMX_DWORD dwSystemID); +FILE* UTF16TempFromUTF8(FILE* fp_in , KMX_BOOL hasPreamble); +KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, FILE* fp_out); +KMX_DWORD AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, KMX_WCHAR const * str, KMX_DWORD *dwStoreID= NULL); +KMX_DWORD ReadLine(FILE* fp_in , PKMX_WCHAR wstr, KMX_BOOL PreProcess); +KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str); +KMX_DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); +KMX_DWORD ProcessGroupFinish(PFILE_KEYBOARD fk); +KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); +int LineTokenType(PKMX_WCHAR *str); +KMX_DWORD BuildVKDictionary(PFILE_KEYBOARD fk); // I3438 diff --git a/developer/src/kmcmplib/src/kmx_u16.cpp b/developer/src/kmcmplib/src/kmx_u16.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6162f532af6448f91af04dbdc79faba6d0a4a8bf --- /dev/null +++ b/developer/src/kmcmplib/src/kmx_u16.cpp @@ -0,0 +1,296 @@ + +//#include "../../kmcompx/include/kmcompx.h" +#include +#include "kmx_u16.h" + +#include +#include +#include +#include +#include +#include + +//String <- wstring +std::string string_from_wstring(std::wstring const str) { + std::wstring_convert, wchar_t> converter; + return converter.to_bytes(str); +} +//wstring <- string +std::wstring wstring_from_string(std::string const str) { + std::wstring_convert, wchar_t> converter; + return converter.from_bytes(str); +} + +//u16String <- string +std::u16string u16string_from_string(std::string const str) { + std::wstring_convert, char16_t> converter; + return converter.from_bytes(str); +} + +//string <- u16string +std::string string_from_u16string(std::u16string const str) { + std::wstring_convert, char16_t> converter; + return converter.to_bytes(str); +} + +// often used with c_str() e.g. u16fmt( DEBUGSTORE_MATCH).c_str() +// UTF16 (= const char16_t*) -> UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) +std::wstring u16fmt(const KMX_WCHAR * str) { + std::wstring_convert, wchar_t> convert_wstring; + std::wstring_convert, char16_t> convert; + + // UTF16 (= const char16_t*) -> UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) + std::string utf8str = convert.to_bytes(str); // UTF16 (= const char16_t*) -> UTF8 (= std::string) + std::wstring wstr = convert_wstring.from_bytes(utf8str); // UTF8 (= std::string) -> UTF16 ( = std::wstring 16 bit) + return wstr; +} + +void u16sprintf(KMX_WCHAR * dst, const size_t sz, const wchar_t* fmt, ...) { + // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) + wchar_t* wbuf = new wchar_t[sz]; + va_list args; + va_start(args, fmt); + vswprintf(wbuf, sz, fmt, args); + va_end(args); + + std::wstring_convert, wchar_t> convert_wstring; + std::wstring_convert, char16_t> convert; + + // UTF16 (=const wchar_t*) -> -> std::string -> std::u16string -> UTF16 ( = char16_t*) + std::string utf8str = convert_wstring.to_bytes(wbuf); // UTF16 ( = const wchar_t*) -> std::string + std::u16string u16str = convert.from_bytes(utf8str); // std::string -> std::u16string + u16ncpy(dst, u16str.c_str(), sz); // std::u16string.c_str() -> char16_t* + delete[] wbuf; +} + + std::wstring convert_pchar16T_To_wstr(KMX_WCHAR *Name){ + // convert char16_t* -> std::u16string -> std::string -> std::wstring + // char16_t* -> std::u16string + std::u16string u16str(Name); + // std::u16string -> std::string + std::string stri = string_from_u16string(u16str); + // std::string -> std::wstring + std::wstring wstr = wstring_from_string(stri); + return wstr; + } + +long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) +{ + auto s = string_from_u16string(str); + char* t; + long int result = strtol(s.c_str(), &t, base); + if (endptr != nullptr) *endptr = (KMX_WCHAR*)str + (t - s.c_str()); + return result; +} + +std::string toHex(int num1) { + if (num1 == 0) + return "0"; + int num = num1; + std::string s = ""; + while (num) { + int temp = num % 16; + if (temp <= 9) + s += (48 + temp); + else + s += (87 + temp); + num = num / 16; + } + reverse(s.begin(), s.end()); + return s; +} + +const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) { + KMX_WCHAR* o = dst; + dst = (KMX_WCHAR*) u16chr(dst, 0); + //max -= (dst-o); + while (*src && max > 0) { + *dst++ = *src++; + max--; + } + if(max > 0) + *dst = 0; + return o; +} + +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name) +{ + const KMX_WCHAR* cp = NULL; + cp = u16rchr(Name, '\\'); + if (cp == NULL) + cp = u16rchr(Name, '/'); + return cp; +} + +KMX_CHAR* strrchr_slash(KMX_CHAR* Name) +{ + KMX_CHAR* cp = NULL; + cp = strrchr(Name, '\\'); + if (cp == NULL) + cp = strrchr(Name, '/'); + return cp; +} + +// u16rchr returns last occurence of ch in p; It returns NULL if ch = '\0' and NULL if ch is not found +const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) { + const KMX_WCHAR* p_end = p + u16len(p) - 1; + + if (ch == '\0') return p_end + 1; + while (p_end >= p) { + if (*p_end == ch) return p_end; + p_end--; + } + return NULL; +} + +const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch) { + while (*p) { + if (*p == ch) return p; + p++; + } + return ch == 0 ? p : NULL; +} + +const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src) { + KMX_WCHAR *o = dst; + while (*src) { + *dst++ = *src++; + } + *dst = 0; + return o; +} + +const KMX_WCHAR * u16ncpy(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max) { + KMX_WCHAR *o = dst; + while (*src && max > 0) { + *dst++ = *src++; + max--; + } + while(max > 0) { + *dst++ = 0; + max--; + } + return o; +} + +size_t u16len(const KMX_WCHAR *p) { + int i = 0; + while (*p) { + p++; + i++; + } + return i; +} + +int u16cmp(const KMX_WCHAR *p, const KMX_WCHAR *q) { + while (*p && *q) { + if (*p != *q) return *p - *q; + p++; + q++; + } + return *p - *q; +} + +int u16nicmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { + while (*p && *q && count) { + if (toupper(*p) != toupper(*q)) return *p - *q; + p++; + q++; + count--; + } + if (count) + return *p - *q; + return 0; +} + +int u16icmp(const KMX_WCHAR *p, const KMX_WCHAR *q) { + while (*p && *q) { + if (toupper(*p) != toupper(*q)) return *p - *q; + p++; + q++; + } + return *p - *q; +} + +int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) { + while (*p && *q && count) { + if (*p != *q) return *p - *q; + p++; + q++; + count--; + } + if (count) + return *p - *q; + return 0; +} + +KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) { + if (!p) { + p = *ctx; + if (!p) return NULL; + } + + KMX_WCHAR *q = p; + while (*q && *q != ch) { + q++; + } + if (*q) { + *q = 0; + q++; + while (*q == ch) q++; + *ctx = q; + } + else { + *ctx = NULL; + } + return p; +} + +KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* delim, KMX_WCHAR** ctx) { + if (!p) { + p = *ctx; + if (!p) return NULL; + } + + KMX_WCHAR * q = p; + while (*q && !u16chr(delim, *q)) { + q++; + } + if (*q) { + *q = 0; + q++; + while (u16chr(delim, *q)) q++; + *ctx = q; + } + else { + *ctx = NULL; + } + return p; +} + +double u16tof( KMX_WCHAR* str) +{ + double val = 0; + int offsetdot=0; + char digit; + + PKMX_WCHAR q = (PKMX_WCHAR)u16chr(str, '.'); + int pos_dot = q-str ; + + if (pos_dot < 0) + pos_dot = u16len(str); + + for (int i = 0; i < u16len(str); i++) + { + digit = static_cast(towupper(*str)); + + if (i > pos_dot - 1) + offsetdot = 1; + + if (digit != '.') + val =val+ ((int(digit)) - 48) * pow(10, (pos_dot - 1- i + offsetdot)); + + str++; + } + return val; +} diff --git a/developer/src/kmcmplib/src/kmx_u16.h b/developer/src/kmcmplib/src/kmx_u16.h new file mode 100644 index 0000000000000000000000000000000000000000..99ad2006bbbe57c57734a1a57c71e4538e318972 --- /dev/null +++ b/developer/src/kmcmplib/src/kmx_u16.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include +#include "kmcompx.h" + +std::string string_from_wstring(std::wstring const str); +std::wstring wstring_from_string(std::string const str); +std::u16string u16string_from_string(std::string const str); +std::string string_from_u16string(std::u16string const str); + +std::wstring u16fmt(const KMX_WCHAR * str); +void u16sprintf(KMX_WCHAR * dst, const size_t sz, const wchar_t* fmt, ...) ; + +std::wstring convert_pchar16T_To_wstr(KMX_WCHAR *Name); + +size_t u16len(const KMX_WCHAR *p); +int u16cmp(const KMX_WCHAR *p, const KMX_WCHAR *q); +int u16icmp(const KMX_WCHAR *p, const KMX_WCHAR *q); +int u16ncmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count); +int u16nicmp(const KMX_WCHAR *p, const KMX_WCHAR *q, size_t count) ; +const KMX_WCHAR * u16ncpy(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max); +const KMX_WCHAR * u16cpy(KMX_WCHAR *dst, const KMX_WCHAR *src); +const KMX_WCHAR * u16rchr(const KMX_WCHAR *p, KMX_WCHAR ch) ; +const KMX_WCHAR * u16chr(const KMX_WCHAR *p, KMX_WCHAR ch) ; +const KMX_WCHAR * u16ncat(KMX_WCHAR *dst, const KMX_WCHAR *src, size_t max); +KMX_WCHAR * u16tok(KMX_WCHAR *p, KMX_WCHAR ch, KMX_WCHAR **ctx) ; +KMX_WCHAR * u16tok(KMX_WCHAR* p, KMX_WCHAR* ch, KMX_WCHAR** ctx) ; +long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) ; +double u16tof( KMX_WCHAR* str); + +KMX_CHAR* strrchr_slash(KMX_CHAR* Name); +const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name); + +std::string toHex(int num1); diff --git a/developer/src/kmcmplib/src/meson.build b/developer/src/kmcmplib/src/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..6ac2b97cec1fa1aa43269652308cec7623ea6afd --- /dev/null +++ b/developer/src/kmcmplib/src/meson.build @@ -0,0 +1,83 @@ +# +# Keyman is copyright (C) SIL International. MIT License. +# +# Cross platform build script to compile kmcompx +# + +# TODO: is this required? It should be Keyman Core only +defns += ['-DKMN_KBP_EXPORTING'] +version_res = [] + +if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' + warns += [ + '-Wall', + '-Wextra' + ] +endif + +if cpp_compiler.get_id() == 'msvc' + # /n = append null + # /c65001 = utf-8 file format + version_res += import('windows').compile_resources('version.rc', args:['/n','/c65001']) +endif + +name_suffix = [] + +if cpp_compiler.get_id() == 'emscripten' + links += ['-lnodefs.js', '-sMODULARIZE', '-sEXPORT_ES6', '-sEXPORTED_RUNTIME_METHODS=[\'cwrap\', \'UTF8ToString\']'] + # tests are building as ES6 so we need to declare the file extension + # note that meson currently struggles with the sanitycheckc_cross.exe + # program, because it has a hard coded extension (.exe) which is not + # valid for node programs in module mode. + name_suffix = '.mjs' +endif + + +lib = library('kmcmplib', + 'CasedKeys.cpp', + 'CharToKeyConversion.cpp', + 'Compiler.cpp', + 'CompilerInterfaces.cpp', + 'DeprecationChecks.cpp', + 'Edition.cpp', + 'filesystem.cpp', + 'json-validation.cpp', + 'NamedCodeConstants.cpp', + 'versioning.cpp', + 'virtualcharkeys.cpp', + 'xstring.cpp', + 'CharToKeyConversion.cpp', + 'CheckFilenameConsistency.cpp', + 'CheckForDuplicates.cpp', + 'CheckNCapsConsistency.cpp', + 'UnreachableRules.cpp', + 'kmx_u16.cpp', + 'CompMsg.cpp', + + '../../../../common/windows/cpp/src/ConvertUTF.c', + '../../../../common/windows/cpp/src/crc32.cpp', + '../../../../common/windows/cpp/src/vkeys.cpp', + 'xstring.cpp', + + '../../ext/json-schema-validator/json-schema-draft4.json.cpp', + '../../ext/json-schema-validator/json-uri.cpp', + '../../ext/json-schema-validator/json-validator.cpp', + version_res, + cpp_args: defns + warns + flags, + link_args: links, + version: meson.project_version(), + include_directories: inc, + install: true) + +kmcmplib = declare_dependency(link_with: lib, include_directories: inc) + + +if cpp_compiler.get_id() == 'emscripten' + # Build an executable + host = executable('wasm-host', #'wasm-host.cpp', + cpp_args: defns, + include_directories: inc, + link_args: links, + objects: lib.extract_all_objects()) +endif + diff --git a/developer/src/kmcmplib/src/pch.cpp b/developer/src/kmcmplib/src/pch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17305716aacd2a39a54423c3fb2000dc2266794a --- /dev/null +++ b/developer/src/kmcmplib/src/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" \ No newline at end of file diff --git a/developer/src/kmcmplib/src/pch.h b/developer/src/kmcmplib/src/pch.h new file mode 100644 index 0000000000000000000000000000000000000000..f878ad11be4f892ad4e9f0ece5864712c6af5c6b --- /dev/null +++ b/developer/src/kmcmplib/src/pch.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#define USE_CHAR16_T +#include +#include "kmx_u16.h" +#include + +#include "../../../../common/windows/cpp/include/crc32.h" + +#include +#include + +#include diff --git a/developer/src/kmcmplib/src/version.rc b/developer/src/kmcmplib/src/version.rc new file mode 100644 index 0000000000000000000000000000000000000000..685b3ff8e4bab7e95ce1cefd4e89b09e85d93b48 --- /dev/null +++ b/developer/src/kmcmplib/src/version.rc @@ -0,0 +1,32 @@ +#include "../../../../common/windows/cpp/include/keymanversion.h" + +1 VERSIONINFO + FILEVERSION KV_FILEVERSION + PRODUCTVERSION KV_PRODUCTVERSION + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0C0904E4" + BEGIN + VALUE "CompanyName", KV_COMPANY_NAME + VALUE "FileDescription", "Keyman compiler library\0" + VALUE "FileVersion", KV_VERSION_STRING + VALUE "InternalName", "KMCOMP\0" + VALUE "LegalCopyright", KV_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", KV_LEGAL_TRADEMARKS + VALUE "OriginalFilename", "KMCOMP.DLL\0" + VALUE "ProductName", "Keyman Developer\0" + VALUE "ProductVersion", KV_VERSION_STRING + VALUE "Comments", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0xc09, 1252 + END + END diff --git a/developer/src/kmcmplib/src/versioning.cpp b/developer/src/kmcmplib/src/versioning.cpp new file mode 100644 index 0000000000000000000000000000000000000000..df85aafd5a319369caac8be253ebbab383552013 --- /dev/null +++ b/developer/src/kmcmplib/src/versioning.cpp @@ -0,0 +1,34 @@ +#include "pch.h" +#include "compfile.h" +#include +#include "kmcmplib.h" +#include "versioning.h" + +KMX_BOOL kmcmp::CheckKeyboardFinalVersion(PFILE_KEYBOARD fk) { + KMX_CHAR buf[128]; + + if (fk->dwFlags & KF_AUTOMATICVERSION) { + if (fk->version <= 0) { + fk->version = VERSION_60; // minimum version that we can be safe with + } + + sprintf(buf, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (int)((fk->version & 0xFF00) >> 8), (int)(fk->version & 0xFF)); + AddCompileWarning(buf); + } + + return TRUE; +} + +// Note: max is not a standard c api function or macro +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +KMX_BOOL VerifyKeyboardVersion(PFILE_KEYBOARD fk, KMX_DWORD ver) { + if (fk->dwFlags & KF_AUTOMATICVERSION) { + fk->version = max(fk->version, ver); + return TRUE; + } + + return fk->version >= ver; +} diff --git a/developer/src/kmcmplib/src/versioning.h b/developer/src/kmcmplib/src/versioning.h new file mode 100644 index 0000000000000000000000000000000000000000..a3a1c597bf668930e76dc4989ced254ad62ea0f3 --- /dev/null +++ b/developer/src/kmcmplib/src/versioning.h @@ -0,0 +1,15 @@ +#pragma once + +#include "compfile.h" +#include "../../../../common/include/km_types.h" + +#define VERIFY_KEYBOARD_VERSION(fk, ver, err) { \ + if(!VerifyKeyboardVersion((fk), (ver))) \ + return (err); \ +} + +namespace kmcmp { + KMX_BOOL CheckKeyboardFinalVersion(PFILE_KEYBOARD fk); +} + +KMX_BOOL VerifyKeyboardVersion(PFILE_KEYBOARD fk, KMX_DWORD ver); diff --git a/developer/src/kmcmplib/src/virtualcharkeys.cpp b/developer/src/kmcmplib/src/virtualcharkeys.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eaef45aac4eb3bef64e47d7abb4a8b39e906bcf0 --- /dev/null +++ b/developer/src/kmcmplib/src/virtualcharkeys.cpp @@ -0,0 +1,274 @@ +#include "pch.h" +#include "virtualcharkeys.h" + +KMX_BOOL VKeyMayBeVCKey[256] = { + FALSE, // L"K_?00", // &H0 + FALSE, // L"K_LBUTTON", // &H1 + FALSE, // L"K_RBUTTON", // &H2 + FALSE, // L"K_CANCEL", // &H3 + FALSE, // L"K_MBUTTON", // &H4 + FALSE, // L"K_?05", // &H5 + FALSE, // L"K_?06", // &H6 + FALSE, // L"K_?07", // &H7 + FALSE, // L"K_BKSP", // &H8 + FALSE, // L"K_TAB", // &H9 + FALSE, // L"K_?0A", // &HA + FALSE, // L"K_?0B", // &HB + FALSE, // L"K_KP5", // &HC + FALSE, // L"K_ENTER", // &HD + FALSE, // L"K_?0E", // &HE + FALSE, // L"K_?0F", // &HF + FALSE, // L"K_SHIFT", // &H10 + FALSE, // L"K_CONTROL", // &H11 + FALSE, // L"K_ALT", // &H12 + FALSE, // L"K_PAUSE", // &H13 + FALSE, // L"K_CAPS", // &H14 + FALSE, // L"K_KANJI?15", // &H15 + FALSE, // L"K_KANJI?16", // &H16 + FALSE, // L"K_KANJI?17", // &H17 + FALSE, // L"K_KANJI?18", // &H18 + FALSE, // L"K_KANJI?19", // &H19 + FALSE, // L"K_?1A", // &H1A + FALSE, // L"K_ESC", // &H1B + FALSE, // L"K_KANJI?1C", // &H1C + FALSE, // L"K_KANJI?1D", // &H1D + FALSE, // L"K_KANJI?1E", // &H1E + FALSE, // L"K_KANJI?1F", // &H1F + TRUE, // L"K_SPACE", // &H20 + FALSE, // L"K_PGUP", // &H21 + FALSE, // L"K_PGDN", // &H22 + FALSE, // L"K_END", // &H23 + FALSE, // L"K_HOME", // &H24 + FALSE, // L"K_LEFT", // &H25 + FALSE, // L"K_UP", // &H26 + FALSE, // L"K_RIGHT", // &H27 + FALSE, // L"K_DOWN", // &H28 + FALSE, // L"K_SEL", // &H29 + FALSE, // L"K_PRINT", // &H2A + FALSE, // L"K_EXEC", // &H2B + FALSE, // L"K_PRTSCN", // &H2C + FALSE, // L"K_INS", // &H2D + FALSE, // L"K_DEL", // &H2E + FALSE, // L"K_HELP", // &H2F + TRUE, // L"K_0", // &H30 + TRUE, // L"K_1", // &H31 + TRUE, // L"K_2", // &H32 + TRUE, // L"K_3", // &H33 + TRUE, // L"K_4", // &H34 + TRUE, // L"K_5", // &H35 + TRUE, // L"K_6", // &H36 + TRUE, // L"K_7", // &H37 + TRUE, // L"K_8", // &H38 + TRUE, // L"K_9", // &H39 + FALSE, // L"K_?3A", // &H3A + FALSE, // L"K_?3B", // &H3B + FALSE, // L"K_?3C", // &H3C + FALSE, // L"K_?3D", // &H3D + FALSE, // L"K_?3E", // &H3E + FALSE, // L"K_?3F", // &H3F + FALSE, // L"K_?40", // &H40 + + TRUE, // L"K_A", // &H41 + TRUE, // L"K_B", // &H42 + TRUE, // L"K_C", // &H43 + TRUE, // L"K_D", // &H44 + TRUE, // L"K_E", // &H45 + TRUE, // L"K_F", // &H46 + TRUE, // L"K_G", // &H47 + TRUE, // L"K_H", // &H48 + TRUE, // L"K_I", // &H49 + TRUE, // L"K_J", // &H4A + TRUE, // L"K_K", // &H4B + TRUE, // L"K_L", // &H4C + TRUE, // L"K_M", // &H4D + TRUE, // L"K_N", // &H4E + TRUE, // L"K_O", // &H4F + TRUE, // L"K_P", // &H50 + TRUE, // L"K_Q", // &H51 + TRUE, // L"K_R", // &H52 + TRUE, // L"K_S", // &H53 + TRUE, // L"K_T", // &H54 + TRUE, // L"K_U", // &H55 + TRUE, // L"K_V", // &H56 + TRUE, // L"K_W", // &H57 + TRUE, // L"K_X", // &H58 + TRUE, // L"K_Y", // &H59 + TRUE, // L"K_Z", // &H5A + FALSE, // L"K_?5B", // &H5B + FALSE, // L"K_?5C", // &H5C + FALSE, // L"K_?5D", // &H5D + FALSE, // L"K_?5E", // &H5E + FALSE, // L"K_?5F", // &H5F + FALSE, // L"K_NP0", // &H60 + FALSE, // L"K_NP1", // &H61 + FALSE, // L"K_NP2", // &H62 + FALSE, // L"K_NP3", // &H63 + FALSE, // L"K_NP4", // &H64 + FALSE, // L"K_NP5", // &H65 + FALSE, // L"K_NP6", // &H66 + FALSE, // L"K_NP7", // &H67 + FALSE, // L"K_NP8", // &H68 + FALSE, // L"K_NP9", // &H69 + FALSE, // L"K_NPSTAR", // &H6A + FALSE, // L"K_NPPLUS", // &H6B + FALSE, // L"K_SEPARATOR", // &H6C + FALSE, // L"K_NPMINUS", // &H6D + FALSE, // L"K_NPDOT", // &H6E + FALSE, // L"K_NPSLASH", // &H6F + FALSE, // L"K_F1", // &H70 + FALSE, // L"K_F2", // &H71 + FALSE, // L"K_F3", // &H72 + FALSE, // L"K_F4", // &H73 + FALSE, // L"K_F5", // &H74 + FALSE, // L"K_F6", // &H75 + FALSE, // L"K_F7", // &H76 + FALSE, // L"K_F8", // &H77 + FALSE, // L"K_F9", // &H78 + FALSE, // L"K_F10", // &H79 + FALSE, // L"K_F11", // &H7A + FALSE, // L"K_F12", // &H7B + FALSE, // L"K_F13", // &H7C + FALSE, // L"K_F14", // &H7D + FALSE, // L"K_F15", // &H7E + FALSE, // L"K_F16", // &H7F + FALSE, // L"K_F17", // &H80 + FALSE, // L"K_F18", // &H81 + FALSE, // L"K_F19", // &H82 + FALSE, // L"K_F20", // &H83 + FALSE, // L"K_F21", // &H84 + FALSE, // L"K_F22", // &H85 + FALSE, // L"K_F23", // &H86 + FALSE, // L"K_F24", // &H87 + + FALSE, // L"K_?88", // &H88 + FALSE, // L"K_?89", // &H89 + FALSE, // L"K_?8A", // &H8A + FALSE, // L"K_?8B", // &H8B + FALSE, // L"K_?8C", // &H8C + FALSE, // L"K_?8D", // &H8D + FALSE, // L"K_?8E", // &H8E + FALSE, // L"K_?8F", // &H8F + + FALSE, // L"K_NUMLOCK", // &H90 + FALSE, // L"K_SCROLL", // &H91 + + FALSE, // L"K_?92", // &H92 + FALSE, // L"K_?93", // &H93 + FALSE, // L"K_?94", // &H94 + FALSE, // L"K_?95", // &H95 + FALSE, // L"K_?96", // &H96 + FALSE, // L"K_?97", // &H97 + FALSE, // L"K_?98", // &H98 + FALSE, // L"K_?99", // &H99 + FALSE, // L"K_?9A", // &H9A + FALSE, // L"K_?9B", // &H9B + FALSE, // L"K_?9C", // &H9C + FALSE, // L"K_?9D", // &H9D + FALSE, // L"K_?9E", // &H9E + FALSE, // L"K_?9F", // &H9F + FALSE, // L"K_?A0", // &HA0 + FALSE, // L"K_?A1", // &HA1 + FALSE, // L"K_?A2", // &HA2 + FALSE, // L"K_?A3", // &HA3 + FALSE, // L"K_?A4", // &HA4 + FALSE, // L"K_?A5", // &HA5 + FALSE, // L"K_?A6", // &HA6 + FALSE, // L"K_?A7", // &HA7 + FALSE, // L"K_?A8", // &HA8 + FALSE, // L"K_?A9", // &HA9 + FALSE, // L"K_?AA", // &HAA + FALSE, // L"K_?AB", // &HAB + FALSE, // L"K_?AC", // &HAC + FALSE, // L"K_?AD", // &HAD + FALSE, // L"K_?AE", // &HAE + FALSE, // L"K_?AF", // &HAF + FALSE, // L"K_?B0", // &HB0 + FALSE, // L"K_?B1", // &HB1 + FALSE, // L"K_?B2", // &HB2 + FALSE, // L"K_?B3", // &HB3 + FALSE, // L"K_?B4", // &HB4 + FALSE, // L"K_?B5", // &HB5 + FALSE, // L"K_?B6", // &HB6 + FALSE, // L"K_?B7", // &HB7 + FALSE, // L"K_?B8", // &HB8 + FALSE, // L"K_?B9", // &HB9 + + TRUE, // L"K_COLON", // &HBA + TRUE, // L"K_EQUAL", // &HBB + TRUE, // L"K_COMMA", // &HBC + TRUE, // L"K_HYPHEN", // &HBD + TRUE, // L"K_PERIOD", // &HBE + TRUE, // L"K_SLASH", // &HBF + TRUE, // L"K_BKQUOTE", // &HC0 + + TRUE, // L"K_?C1", // &HC1 -- 103rd key on Brazilian - /? + FALSE, // L"K_?C2", // &HC2 -- 104th key on Brazilian - numpad . + FALSE, // L"K_?C3", // &HC3 + FALSE, // L"K_?C4", // &HC4 + FALSE, // L"K_?C5", // &HC5 + FALSE, // L"K_?C6", // &HC6 + FALSE, // L"K_?C7", // &HC7 + FALSE, // L"K_?C8", // &HC8 + FALSE, // L"K_?C9", // &HC9 + FALSE, // L"K_?CA", // &HCA + FALSE, // L"K_?CB", // &HCB + FALSE, // L"K_?CC", // &HCC + FALSE, // L"K_?CD", // &HCD + FALSE, // L"K_?CE", // &HCE + FALSE, // L"K_?CF", // &HCF + FALSE, // L"K_?D0", // &HD0 + FALSE, // L"K_?D1", // &HD1 + FALSE, // L"K_?D2", // &HD2 + FALSE, // L"K_?D3", // &HD3 + FALSE, // L"K_?D4", // &HD4 + FALSE, // L"K_?D5", // &HD5 + FALSE, // L"K_?D6", // &HD6 + FALSE, // L"K_?D7", // &HD7 + FALSE, // L"K_?D8", // &HD8 + FALSE, // L"K_?D9", // &HD9 + FALSE, // L"K_?DA", // &HDA + + TRUE, // L"K_LBRKT", // &HDB + TRUE, // L"K_BKSLASH", // &HDC + TRUE, // L"K_RBRKT", // &HDD + TRUE, // L"K_QUOTE", // &HDE + TRUE, // L"K_oDF", // &HDF + TRUE, // L"K_oE0", // &HE0 + TRUE, // L"K_oE1", // &HE1 + TRUE, // L"K_oE2", // &HE2 + TRUE, // L"K_oE3", // &HE3 + TRUE, // L"K_oE4", // &HE4 + + FALSE, // L"K_?E5", // &HE5 + + TRUE, // L"K_oE6", // &HE6 + + FALSE, // L"K_?E7", // &HE7 + FALSE, // L"K_?E8", // &HE8 + + TRUE, // L"K_oE9", // &HE9 + TRUE, // L"K_oEA", // &HEA + TRUE, // L"K_oEB", // &HEB + TRUE, // L"K_oEC", // &HEC + TRUE, // L"K_oED", // &HED + TRUE, // L"K_oEE", // &HEE + TRUE, // L"K_oEF", // &HEF + TRUE, // L"K_oF0", // &HF0 + TRUE, // L"K_oF1", // &HF1 + TRUE, // L"K_oF2", // &HF2 + TRUE, // L"K_oF3", // &HF3 + TRUE, // L"K_oF4", // &HF4 + TRUE, // L"K_oF5", // &HF5 + + FALSE, // L"K_?F6", // &HF6 + FALSE, // L"K_?F7", // &HF7 + FALSE, // L"K_?F8", // &HF8 + FALSE, // L"K_?F9", // &HF9 + FALSE, // L"K_?FA", // &HFA + FALSE, // L"K_?FB", // &HFB + FALSE, // L"K_?FC", // &HFC + FALSE, // L"K_?FD", // &HFD + FALSE, // L"K_?FE", // &HFE + FALSE, // L"K_?FF" // &HFF + }; + diff --git a/developer/src/kmcmplib/src/virtualcharkeys.h b/developer/src/kmcmplib/src/virtualcharkeys.h new file mode 100644 index 0000000000000000000000000000000000000000..539c5c5d4075e19e95f38ecee901bb409634bbd6 --- /dev/null +++ b/developer/src/kmcmplib/src/virtualcharkeys.h @@ -0,0 +1,7 @@ +#ifndef _VIRTUALCHARKEYS_H +#define _VIRTUALCHARKEYS_H + +extern KMX_BOOL VKeyMayBeVCKey[256]; + +#endif + diff --git a/developer/src/kmcmplib/src/xstring.cpp b/developer/src/kmcmplib/src/xstring.cpp new file mode 100644 index 0000000000000000000000000000000000000000..870e991656c08d95dd461fab4613ea61eb62aee5 --- /dev/null +++ b/developer/src/kmcmplib/src/xstring.cpp @@ -0,0 +1,152 @@ + +#include "pch.h" +#include "xstring.h" +// used to be windows/src/global/vc/xstring.cpp +/* +* int xstrlen( PKMX_BYTE p ); +* +* Parameters: p Pointer to string to get length of +* +* Returns: length of string +* +* Called by: various functions +* +* xstrlen calculates the length of a string, ignoring some special chars. +*/ +PKMX_WCHAR incxstr(PKMX_WCHAR p) { + + if (*p == 0) + return p; + if (*p != UC_SENTINEL) { + if (*p >= 0xD800 && *p <= 0xDBFF && *(p + 1) >= 0xDC00 && *(p + 1) <= 0xDFFF) + return p + 2; + return p + 1; + } + // UC_SENTINEL(FFFF) with UC_SENTINEL_EXTENDEDEND(0x10) == variable length + if (*(p + 1) == CODE_EXTENDED) { + p += 2; + while (*p && *p != UC_SENTINEL_EXTENDEDEND) + p++; + + if (*p == 0) return p; + return p + 1; + } + + if (*(p + 1) > CODE_LASTCODE || CODE__SIZE[*(p + 1)] == -1) { + return p + 1; + } + + int deltaptr = 2 + CODE__SIZE[*(p + 1)]; + + // check for \0 between UC_SENTINEL(FFFF) and next printable character + for (int i = 0; i < deltaptr; i++) { + if (*p == 0) + return p; + p++; + } + return p; +} + +PKMX_WCHAR decxstr(PKMX_WCHAR p, PKMX_WCHAR pStart) +{ + PKMX_WCHAR q; + + if(p <= pStart) { + return NULL; + } + + p--; + if(*p == UC_SENTINEL_EXTENDEDEND) { + int n = 0; + while (p > pStart && *p != UC_SENTINEL && n < 10) { + p--; + n++; + } + + return p; + } + + if (p == pStart) { + // Don't allow test before pStart + return p; + } + + if(*p >= 0xDC00 && *p <= 0xDFFF && *(p-1) >= 0xD800 && *(p-1) <= 0xDBFF) { + return p-1; + } + + // Look for a UC_SENTINEL to jump to + // note: If we are pointing to the middle of a UC_SENTINEL CODE_x, then we won't treat it as valid, + // and will just go back a single wchar + q = p; + for (int i = 0; i < CODE__SIZE_MAX && q >= pStart; i++, q--) { + // *q == UC_SENTINEL && *(q + 1) is within CODE__SIZE && next CODE_ right of UC_SENTINEL ( looked up in CODE__SIZE+1) has value i + if (*q == UC_SENTINEL && *(q + 1) <= CODE_LASTCODE && CODE__SIZE[*(q + 1)] + 1 == i) + return q; + } + + return p; +} + +int xstrlen_ignoreifopt(PKMX_WCHAR p) +{ + int i; + for(i = 0; *p; i++, p=incxstr(p)) + { + if(*p == UC_SENTINEL && (*(p+1) == CODE_IFOPT || *(p+1) == CODE_IFSYSTEMSTORE)) i--; // I3432 + } + return i; +} + +int xstrlen(PKMX_WCHAR p) +{ + int i; + for(i = 0; *p; i++, p=incxstr(p)); + return i; +} + +int xstrpos(PKMX_WCHAR p1, PKMX_WCHAR p) +{ + int i; + for(i = 0; p < p1; p = incxstr(p), i++); + return i; +} + +PKMX_WCHAR xstrchr(PKMX_WCHAR buf, PKMX_WCHAR chr) +{ + for(PKMX_WCHAR q = incxstr(buf); *buf; buf = q, q = incxstr(buf)) + if(!u16ncmp(buf, chr, (intptr_t)(q-buf))) + return buf; + return NULL; +} + +const int CODE__SIZE[] = { + -1, // undefined 0x00 + 1, // CODE_ANY 0x01 + 2, // CODE_INDEX 0x02 + 0, // CODE_CONTEXT 0x03 + 0, // CODE_NUL 0x04 + 1, // CODE_USE 0x05 + 0, // CODE_RETURN 0x06 + 0, // CODE_BEEP 0x07 + 1, // CODE_DEADKEY 0x08 + -1, // unused 0x09 + 2, // CODE_EXTENDED 0x0A + -1, // CODE_EXTENDEDEND 0x0B (unused) + 1, // CODE_SWITCH 0x0C + -1, // CODE_KEY 0x0D (never used) + 0, // CODE_CLEARCONTEXT 0x0E + 1, // CODE_CALL 0x0F + -1, // UC_SENTINEL_EXTENDEDEND 0x10 (not valid with UC_SENTINEL) + 1, // CODE_CONTEXTEX 0x11 + 1, // CODE_NOTANY 0x12 + 2, // CODE_SETOPT 0x13 + 3, // CODE_IFOPT 0x14 + 1, // CODE_SAVEOPT 0x15 + 1, // CODE_RESETOPT 0x16 + 3, // CODE_IFSYSTEMSTORE 0x17 + 2 // CODE_SETSYSTEMSTORE 0x18 +}; + +// Ensure that all CODE_### sizes are defined +static_assert(sizeof(CODE__SIZE) / sizeof(CODE__SIZE[0]) == (CODE_LASTCODE + 1), "Size of array CODE__SIZE not correct"); diff --git a/developer/src/kmcmplib/src/xstring.h b/developer/src/kmcmplib/src/xstring.h new file mode 100644 index 0000000000000000000000000000000000000000..ae08cfe64a2ef22a941fe67c5ba1047551735cef --- /dev/null +++ b/developer/src/kmcmplib/src/xstring.h @@ -0,0 +1,15 @@ +// TODO: merge with xstring.h from common +#pragma once +#ifndef XSTRING_H +#define SXTRING_H +#include + +KMX_UCHAR* incxstr(KMX_UCHAR* p); +KMX_UCHAR* decxstr(KMX_UCHAR* p, KMX_UCHAR* pStart); +int xstrlen(KMX_UCHAR* p); +int xstrlen_ignoreifopt(KMX_UCHAR* p); +int xstrpos(KMX_UCHAR* p1, KMX_UCHAR* p); +KMX_UCHAR* xstrchr(KMX_UCHAR* buf, KMX_UCHAR* chr); +int xchrcmp(KMX_UCHAR* ch1, KMX_UCHAR* ch2); + +#endif // XSTRING_H diff --git a/developer/src/kmcmplib/tests/README.md b/developer/src/kmcmplib/tests/README.md new file mode 100644 index 0000000000000000000000000000000000000000..367c1f9685d4cd489c196e90c81a4ffe22ddb8e5 --- /dev/null +++ b/developer/src/kmcmplib/tests/README.md @@ -0,0 +1,30 @@ +# Unit tests for kmcmplib + +kmcmplib tests include building all keyboards in the keyboards repository and +comparing against a 'known good' legacy compiler set. This is trickier than it +sounds because the legacy compiler only runs under Windows/WINE and we don't +want to introduce a dependency on that for running the tests. + +Instead we've gone the route of adding a pre-compiled set of .kmx fixtures, +alongside a commit ref in keyboards_commit_ref.txt. The test script will +checkout that specific ref in its own private clone of the keyboards repository +(including a shallow clone of the keyboards repo if it isn't already present), +and compiling the sources from that specific commit. + +For performance reasons, it is useful to setup KEYBOARDS_ROOT env var to point +to your local clone of the keyboards repository. The build will make a private +clone of this repo rather than the remote clone if it is available, which is +typically much faster. + +# Preparing fixtures + +prep.sh allows us to regenerate the fixtures with the legacy compiler for +testing. It depends on the regression test scripts in keyboards.sh, and specific +changes introduced into those scripts in +https://github.com/keymanapp/keyboards/pull/2169. + +It is essential that the keyboards repository is clean and checked out to the +commit that you want to be using (usually this will be HEAD of master). All of +Keyman Developer must be built locally and binaries should be in developer/bin/. + +prep.sh has only been tested on Windows, because it relies on kmcomp.exe. diff --git a/developer/src/kmcmplib/tests/api-test.cpp b/developer/src/kmcmplib/tests/api-test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83b83d896b786ca9faac6817616a95c80ddebb68 --- /dev/null +++ b/developer/src/kmcmplib/tests/api-test.cpp @@ -0,0 +1,89 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * API endpoint unit tests for kmcmplib + */ + +#include + +#ifdef _MSC_VER +#include +#else +#include +#endif + +#include +#include +#include +#include "../src/comperr.h" +#include "../src/compfile.h" +#include + +void setup(); +void test_kmcmp_CompileKeyboardFile(); +void test_kmcmp_CompileKeyboardFileToBuffer(); + +std::vector error_vec; + +int msgproc(int line, uint32_t dwMsgCode, char* szText, void* context) { + error_vec.push_back(dwMsgCode); + const char*t = "unknown"; + switch(dwMsgCode & 0xF000) { + case CERR_HINT: t=" hint"; break; + case CERR_WARNING: t="warning"; break; + case CERR_ERROR: t=" error"; break; + case CERR_FATAL: t=" fatal"; break; + } + printf("line %d %s %04.4x: %s\n", line, t, (unsigned int)dwMsgCode, szText); + return 1; +} + +int main(int argc, char *argv[]) { + setup(); + test_kmcmp_CompileKeyboardFile(); + + setup(); + test_kmcmp_CompileKeyboardFileToBuffer(); + + return 0; +} + +void setup() { + error_vec.clear(); +} + +void test_kmcmp_CompileKeyboardFile() { + char kmn_file[L_tmpnam], kmx_file[L_tmpnam]; + tmpnam(kmn_file); + tmpnam(kmx_file); + + // Create an empty file + FILE *fp = fopen(kmn_file, "w"); + fclose(fp); + + // It should fail when a zero-byte file is passed in + assert(!kmcmp_CompileKeyboardFile(kmn_file, kmx_file, true, false, true, msgproc, nullptr)); + assert(error_vec.size() == 1); + assert(error_vec[0] == CERR_CannotReadInfile); + + unlink(kmn_file); +} + +void test_kmcmp_CompileKeyboardFileToBuffer() { + char kmn_file[L_tmpnam], kmx_file[L_tmpnam]; + tmpnam(kmn_file); + tmpnam(kmx_file); + + // Create an empty file + FILE *fp = fopen(kmn_file, "w"); + fclose(fp); + + FILE_KEYBOARD fk; + + // It should fail when a zero-byte file is passed in + assert(!kmcmp_CompileKeyboardFileToBuffer(kmn_file, &fk, true, false, msgproc, nullptr, CKF_KEYMAN)); + assert(error_vec.size() == 1); + assert(error_vec[0] == CERR_CannotReadInfile); + + unlink(kmn_file); +} \ No newline at end of file diff --git a/developer/src/kmcmplib/tests/fixtures/adiga_danef.kmx b/developer/src/kmcmplib/tests/fixtures/adiga_danef.kmx new file mode 100644 index 0000000000000000000000000000000000000000..022254f30cb8d418d80a307b4450d3f7d3f7d58f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/adiga_danef.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/ahom_star.kmx b/developer/src/kmcmplib/tests/fixtures/ahom_star.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bb4a25dc3ed3d5223a66e941d659c7b24327526c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/ahom_star.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/aksarabali_panlex.kmx b/developer/src/kmcmplib/tests/fixtures/aksarabali_panlex.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8ef0107686cda89ffea8ef62630f98b9c5c380d1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/aksarabali_panlex.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/alephwithbeth.kmx b/developer/src/kmcmplib/tests/fixtures/alephwithbeth.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2e2140a47de066096d67d83be4b29e16eae46dd4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/alephwithbeth.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/anii.kmx b/developer/src/kmcmplib/tests/fixtures/anii.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b7364fc6499a0370197eed458058f63aca6624bf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/anii.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/arabic_izza.kmx b/developer/src/kmcmplib/tests/fixtures/arabic_izza.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c573fecd20687968fce217b28d26ef2de91efee9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/arabic_izza.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/aramaic_hebrew.kmx b/developer/src/kmcmplib/tests/fixtures/aramaic_hebrew.kmx new file mode 100644 index 0000000000000000000000000000000000000000..583078c41843337c1471ae45d1b8498643212912 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/aramaic_hebrew.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/armenian_mnemonic.kmx b/developer/src/kmcmplib/tests/fixtures/armenian_mnemonic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8010790e3da2f267e51bd25083d90030c6604ca6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/armenian_mnemonic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/armenian_mnemonic_r.kmx b/developer/src/kmcmplib/tests/fixtures/armenian_mnemonic_r.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d54f85abee2f4a5ce1d42cc39afb0a0a0dcad394 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/armenian_mnemonic_r.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/athinkra_vai.kmx b/developer/src/kmcmplib/tests/fixtures/athinkra_vai.kmx new file mode 100644 index 0000000000000000000000000000000000000000..127914ffe52d26515f0b8332d4857d58fa8f8b96 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/athinkra_vai.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/athinkra_vai_typewriter.kmx b/developer/src/kmcmplib/tests/fixtures/athinkra_vai_typewriter.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cab129cf0b11cdd1eb523e7324d2179128d863bd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/athinkra_vai_typewriter.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/ausephon.kmx b/developer/src/kmcmplib/tests/fixtures/ausephon.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5e1d99345156581ffa851c9a21bb26a8cd90eaee Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/ausephon.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/balochi_inpage.kmx b/developer/src/kmcmplib/tests/fixtures/balochi_inpage.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2d7e0606880adadb6e7e3e6611f7cf5145e4f5dc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/balochi_inpage.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/balochi_latin.kmx b/developer/src/kmcmplib/tests/fixtures/balochi_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5718c9ed54b10dfa73645fd3edcecbbdc185c05b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/balochi_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/balochi_persian.kmx b/developer/src/kmcmplib/tests/fixtures/balochi_persian.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0aa472e7d719e58b40718c238411539d6b091fdc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/balochi_persian.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/balochi_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/balochi_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..38714eb7888a0b8fabf64ca6fbb09c823e680d62 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/balochi_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/balochi_scientific.kmx b/developer/src/kmcmplib/tests/fixtures/balochi_scientific.kmx new file mode 100644 index 0000000000000000000000000000000000000000..20ca365b71c9086fbdfc5d6b58a6e22264688932 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/balochi_scientific.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/balochi_urdu.kmx b/developer/src/kmcmplib/tests/fixtures/balochi_urdu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..43112d0ad470c442a5da3b1e0094af9762a701a7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/balochi_urdu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bangla_joy.kmx b/developer/src/kmcmplib/tests/fixtures/bangla_joy.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6228742eca089c60966479c016e811ba2df6b6b7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bangla_joy.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bangla_munir.kmx b/developer/src/kmcmplib/tests/fixtures/bangla_munir.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ba449452e698810b89b48545b9f637e650fcd26b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bangla_munir.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bangla_probhat.kmx b/developer/src/kmcmplib/tests/fixtures/bangla_probhat.kmx new file mode 100644 index 0000000000000000000000000000000000000000..582b517ef5e54e4751a5b9c2f106911241874aea Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bangla_probhat.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbda1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbda1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a4e8a01c0136104c2ee07323f872e32411c98c5c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbda1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbda2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbda2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..87712cb69cf30d04a15f3f2e084a90fa655910cd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbda2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbda3.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbda3.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dacb36e258a277f875068760172e15002a835105 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbda3.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdadlm.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdadlm.kmx new file mode 100644 index 0000000000000000000000000000000000000000..81159040eea2a41a080e5b21a25ab4f8171e438c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdadlm.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdal.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdal.kmx new file mode 100644 index 0000000000000000000000000000000000000000..797300726e58b26366f5a9dd044b49dca88899bd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdal.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdarme.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdarme.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9210a7fa3a951d9d06fbce7a81b65ae71861f6f4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdarme.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdarmph.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdarmph.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e77ad47a93adb60880dd9238a150d7ca990065c0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdarmph.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdarmty.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdarmty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a02cdd54ba4c8715c64ce37553ae3ba24f3d4425 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdarmty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdarmw.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdarmw.kmx new file mode 100644 index 0000000000000000000000000000000000000000..073ce6d16f55b81a0f5f7dfae9228f6c38bec54e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdarmw.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdaze.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdaze.kmx new file mode 100644 index 0000000000000000000000000000000000000000..490aaac05fe5aeab1cde4bb44d3d677b918895d7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdaze.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdazel.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdazel.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d12f8d6f92749aa8d4fe1ce0c04dfc5db675411a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdazel.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdazst.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdazst.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3c56347f51c3b624f892aec6a3b610d9ffcae01e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdazst.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbash.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbash.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b5c2783d685ceacd2ac104faefb9cf615afae6f2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbash.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbe.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbe.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9000c86436324f8d6f1984de49823aef46366feb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbe.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbene.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbene.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b0d15fa23a599c23e7dae149e6c3e4c1f3ded254 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbene.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbgph.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbgph.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ddd9bded810372f9d5084f3164b033c238142bd1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbgph.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbgph1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbgph1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..284a8878a1f92fbcf178f67c93993ad08675ee36 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbgph1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbhc.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbhc.kmx new file mode 100644 index 0000000000000000000000000000000000000000..937f755ea95c1572c13d38a80bfac9caba3f619b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbhc.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdblr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdblr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2a36c250446e40dfaeb4b30b9da077fd3c27c3b8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdblr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f3d117172c4fb1353ee91451c21b96184ef1dd4b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbu.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8e27a0dbc67e28267ff91e9d03b8a485f3cfac23 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbug.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbug.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c1021e5c7fa13c2b375b21fb8a2ea83ea83b6561 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbug.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdbulg.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdbulg.kmx new file mode 100644 index 0000000000000000000000000000000000000000..88c242a58fa3333c4f6a68cd8f139a4ccede3dd0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdbulg.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdca.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdca.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ebb3bae6ce546dae6b050c07992a2f8d2e74e8df Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdca.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdcan.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdcan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..65e70a2c70643d1155e043aa1acd4d5d82f4a778 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdcan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdcher.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdcher.kmx new file mode 100644 index 0000000000000000000000000000000000000000..792054a8903f8319da5d740621e278754e7e6236 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdcher.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdcherp.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdcherp.kmx new file mode 100644 index 0000000000000000000000000000000000000000..91c769d249377d4342dc979222b295ccaf954188 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdcherp.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdcr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdcr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fe0e9c70486314de772cff54606ebdc746f1762e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdcr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdcz.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdcz.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e293b056cdd0b30acc9a2b52a13442bd9b0ac5a8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdcz.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdcz1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdcz1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5a7243bd93c34d954e2811cf559f036a44bee2a6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdcz1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdcz2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdcz2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8cf0d820b9d749dfb3fde7ce074b4fc78b1a6fda Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdcz2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdda.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdda.kmx new file mode 100644 index 0000000000000000000000000000000000000000..aa282296e347cee97f1bb0dcb2f432ec3ea0a0de Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdda.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbddiv1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbddiv1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eea19450598ecb64afc91dc6f520fb1c17edba2f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbddiv1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbddiv2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbddiv2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a2bf45f00cdff79abc305ac7cb7c553ea1a6c0c0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbddiv2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbddv.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbddv.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f4731412f03e665988e89e21e763aa16c1118d45 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbddv.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbddzo.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbddzo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1b2b2584510ee4d22d429b96e9a07f7fa5a65c01 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbddzo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdes.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdes.kmx new file mode 100644 index 0000000000000000000000000000000000000000..97cd31535da991e80f11fd05e198184cb6c69438 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdes.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdest.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdest.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d66c6984b51ff54618b6b395296b7c212993c5e7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdest.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdfa.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdfa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5c4f44b6ada77244cd511143e11a6fbed224a35c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdfa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdfar.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdfar.kmx new file mode 100644 index 0000000000000000000000000000000000000000..59bcae67d18e2f35a068ef78b0b97642ac88feab Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdfar.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdfi.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdfi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cc53ecc0c6873f956cacc66f947cb9f171ca2d3b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdfi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdfi1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdfi1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fa9d6c4c731b921917261800d55da17e624371f5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdfi1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdfo.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdfo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8aa400b50bed17f949766b8ea20f40dcad2ae5b1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdfo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdfr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdfr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a243166c2ddf8e5c8fb4d38486cb41af1d3e7b3a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdfr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdfthrk.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdfthrk.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bc26f816056204241042f01fb053eeeae0ac635d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdfthrk.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgae.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgae.kmx new file mode 100644 index 0000000000000000000000000000000000000000..31a621f17b6eb2199acd14bda278fa866c78c381 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgae.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgeo.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..458e4ec060bff672178330c1792926f602288ab1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgeoer.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeoer.kmx new file mode 100644 index 0000000000000000000000000000000000000000..107967ba6f6a05b6ef02d3895f515db48680dbe7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeoer.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgeome.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeome.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1ac4c9083d5139c0c83dfae1e945a1982fa54fab Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeome.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgeooa.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeooa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c356eecd7b0f80b6d2dfbf242f9b4c1b12767bdb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeooa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgeoqw.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeoqw.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7e251ebc113aafcaa45faaca87fa58e721d5932a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgeoqw.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgkl.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgkl.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d264860a10731fbea01245b35413e6b0377b9b8e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgkl.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgn.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgn.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cfd3cf5c319211f6b9501734cd053cefb7b9b934 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgn.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..116ee9be91a190128993eb728c32f06700063574 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgr1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgr1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8672a9c7c10c7dd0f1efee665e51fed7ef08c266 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgr1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgrlnd.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgrlnd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dfbc61f0ee8938d292bf1fc7faebc06f56eae6e9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgrlnd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdgthc.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdgthc.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c8ffe27cf7ac2364214d8fce23e6f50d00050136 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdgthc.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhau.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhau.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8486d0af507978fe632a7408628d7bfe53760c67 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhau.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhaw.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhaw.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9cf3c48b9a47602e637ba8b61ed125b5105d9539 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhaw.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhe.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhe.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2268775a7d98bbdfe3ff2deace0509202d0daaac Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhe.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhe220.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhe220.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bdfc400f7537137cc3b4ee438d3e3201a9ac30d5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhe220.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhe319.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhe319.kmx new file mode 100644 index 0000000000000000000000000000000000000000..100fe70446bee6b910d3714743f69a53d898b0fd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhe319.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdheb.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdheb.kmx new file mode 100644 index 0000000000000000000000000000000000000000..72fb99e682fafa1c94c455b2a6417a35d3150b61 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdheb.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhebl3.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhebl3.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b28ab2f42bc09ce6294d8d8f647a65dddb858b37 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhebl3.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhela2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhela2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e52d1e212251c9163e6d75969399161ee51d714e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhela2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhela3.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhela3.kmx new file mode 100644 index 0000000000000000000000000000000000000000..044cc06f26c19c0796a89c79061e77cf1b82d76e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhela3.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhept.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhept.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e629ffda18f00a74a37845a236f9b51e4edd857a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhept.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhu.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..92205a9bd96ecc92cfb6b24327b39829be2930a7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdhu1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdhu1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5d9ff3d278325f97734c741e0307fc9610e2a9f9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdhu1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdibo.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdibo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..081025252b168bc4242f95a02847885950d66052 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdibo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdic.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6d9df2e7a070a4efffde7464d9bc701bcc0d4611 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinasa.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinasa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cac244378355ad3b72d8088ce762300d532823f8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinasa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinbe2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinbe2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..78a5acd3013f77194d0b29d7624dab1e899c7bf7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinbe2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinben.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinben.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a660d951b8d4d394cc6eafaedef45ef0060fefe0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinben.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdindev.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdindev.kmx new file mode 100644 index 0000000000000000000000000000000000000000..32d454daaa42013bb3f4e709222beaa2fc20a18c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdindev.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinen.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinen.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0ce474be7cdf76d9b13884d6488480fb6b2213a6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinen.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinguj.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinguj.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3529d62f77935613be5bd00844a461fc228bd01a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinguj.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinhin.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinhin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..754d7fc8c8b8f735ab7e89ebe211be9fb0da37dd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinhin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinkan.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinkan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..33a2802a734b856c394fe12126018a98c3579ff7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinkan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinmal.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinmal.kmx new file mode 100644 index 0000000000000000000000000000000000000000..00f6e8c4e8d90a996450fe092dddc7763fbaa9ab Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinmal.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinmar.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinmar.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6d7289da4a33dbd7feee2c477d7d028e23600047 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinmar.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinori.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinori.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dfd8244e332eac1875a1116a3f7438229bbb408c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinori.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinpun.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinpun.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5ccb95ae1cf2ae39a1a5b9e5983f8f18131badbb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinpun.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdintam.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdintam.kmx new file mode 100644 index 0000000000000000000000000000000000000000..61fd2637dbfbba3f5315d408429eafe6839f1493 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdintam.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdintel.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdintel.kmx new file mode 100644 index 0000000000000000000000000000000000000000..217f05338f0aee310c33f778522dc108b8c911df Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdintel.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdinuk2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdinuk2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..00b4e83b704c346638a165a753032ee012e4e3cc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdinuk2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdir.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdir.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2df897edd98028fd2febe69f24434e9612c9a81e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdir.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdit.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdit.kmx new file mode 100644 index 0000000000000000000000000000000000000000..97488aaf6305aa9ed89337e66af3b58f53b7254a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdit.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdit142.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdit142.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d8b9d5f487c39b2caf00b5e2c7a66f4f0db0df2d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdit142.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdiulat.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdiulat.kmx new file mode 100644 index 0000000000000000000000000000000000000000..29b9e8cd621fc7eba5b4d8b385cde8a6f37ee970 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdiulat.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdjav.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdjav.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2d903c534f986212184b64a88f035094eb99bbfd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdjav.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdkaz.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdkaz.kmx new file mode 100644 index 0000000000000000000000000000000000000000..aec72e3a967ea872077e58a620d3081ecedce3c2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdkaz.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdkhmr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdkhmr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e1ad6cff7e97e02486fc02403c440d9a8a72512c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdkhmr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdkni.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdkni.kmx new file mode 100644 index 0000000000000000000000000000000000000000..06a5b460b0719d2b77b01cdae5e5f20a86a61a96 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdkni.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdkurd.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdkurd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..86e3cf268033f3ed18a8250c430d6724efc398d2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdkurd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdkyr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdkyr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a6a34652547aff4d9fc9736059b62e43975c4db8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdkyr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdla.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdla.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8bdf865cf2e7d4d5d2032cb4ef089c999a1a3641 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdla.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlao.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlao.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3d9a1552827db8445b383ff98e1de14a8861fee7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlao.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlisub.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlisub.kmx new file mode 100644 index 0000000000000000000000000000000000000000..584fe2cdabd727c9c137f9b45434011b2163e5f3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlisub.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlisus.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlisus.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4fc843fb72f70905942e858fe29f6e77195533ff Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlisus.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlt.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlt.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fc3d74e8e24fa4a5e975682bcf64ce4cb900df57 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlt.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlt1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlt1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0d4a108b46a5751a9b1269a23d9a11347748fde8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlt1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlt2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlt2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c250d4afbf9ac64f17fc450d75efdfb0ea60ba98 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlt2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlv.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlv.kmx new file mode 100644 index 0000000000000000000000000000000000000000..417a7f5a7cb92840619f3f9ed6cddfefddbd11f9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlv.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlv1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlv1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9b599d3f0ff7b0ea13545d693e0f26cbdef605bf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlv1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdlvst.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdlvst.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a1f6d165d3f7b6e3df01c0111d1436d01edc9420 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdlvst.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmac.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmac.kmx new file mode 100644 index 0000000000000000000000000000000000000000..031d3308d35d4e61a5419a619b15730a0fb18c8f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmac.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmacst.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmacst.kmx new file mode 100644 index 0000000000000000000000000000000000000000..300b2b4bfc3f43b6d0a9d82bb6368fca8ff1f95a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmacst.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmaori.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmaori.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b4a23b82c60f332eb3efe6795f168dc46a01b58a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmaori.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmlt47.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmlt47.kmx new file mode 100644 index 0000000000000000000000000000000000000000..16a9866e00416290c169d234eeec44895ad51624 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmlt47.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmlt48.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmlt48.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8168c69548710ac5b694e74e978dfa0775b64c9b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmlt48.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmon.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmon.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7e5e01839e9b29408703e3451b43c1de7a4fbc05 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmon.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmonmo.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmonmo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0eb2da7dfca5662ecff6f0c169ff19f3ec4743ba Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmonmo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmonst.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmonst.kmx new file mode 100644 index 0000000000000000000000000000000000000000..92e3394b6b8974f7510a715df0738b4a1b14a00c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmonst.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdmyan.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdmyan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0b9e74cd8831e382bcf5b7d40dc66f3a3f4cd1a1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdmyan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdne.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdne.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bf71710dbf0890345b13d11f817bd6d2e9117f28 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdne.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdnepr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdnepr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6d828eb350aa115af814062fcf6a9ca7338c19f5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdnepr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdnko.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdnko.kmx new file mode 100644 index 0000000000000000000000000000000000000000..099947ed552dbe68cbb1bd7cfbe7a2b8a6be0da6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdnko.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdno.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdno.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ed63bae4f81ab4de9fab4adc89685872d9c8b0be Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdno.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdno1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdno1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6daa96d5429b64409433d26ae8c344dfd616e1c0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdno1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdnso.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdnso.kmx new file mode 100644 index 0000000000000000000000000000000000000000..342556e10dc02ea8dd5782e81ae188ebe7413e4f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdnso.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdntl.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdntl.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e090efd2e6a0c36911d3881f7ba4f8bb74111944 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdntl.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdogham.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdogham.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b92652758f2e37d19a07e92e9ef0d0b977f92959 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdogham.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdolch.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdolch.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3b2c0e1f950d80a0d7c8ce2fa4dd545ca97f3a08 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdolch.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdoldit.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdoldit.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d4d21fc9bbe685ac90920097e268b1b640f34ab6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdoldit.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdosa.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdosa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..49e2f06fce1239ee3e6c351c556272bd9f6fc6ee Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdosa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdosm.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdosm.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ef355a0eed9b1d94b80b15fcfb71257800fdf13d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdosm.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdpash.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdpash.kmx new file mode 100644 index 0000000000000000000000000000000000000000..56461e805022edc750dba2e14c9b0c925923228b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdpash.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdphags.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdphags.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f76a7c010eb510cef972538b70dbfc1c33136db9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdphags.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdpl.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdpl.kmx new file mode 100644 index 0000000000000000000000000000000000000000..28ebf385cf22e82be75922eb15d3c3dca7961c9d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdpl.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdpl1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdpl1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5034a1f819e48a5aa5b78006f8d6d285db9afadf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdpl1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdpo.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdpo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dbb01e139190c6f7cee5eee943a34ec0ad68ed2f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdpo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdropr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdropr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b5697f6ce5c102e31a79ed35d0fc3619ef322263 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdropr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdrost.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdrost.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8da352fb796608ac33269c83dfae9ac4dadb9b68 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdrost.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdru.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdru.kmx new file mode 100644 index 0000000000000000000000000000000000000000..39963e29cddb310a21b6ab7916325d279fc835f5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdru.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdru1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdru1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3dd977a73b36515a68276eb35471af8f78d92d93 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdru1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdrum.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdrum.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d32a78212f04ae3aac89b4f80aaeb1d8cf158647 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdrum.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsf.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsf.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e990000b160bb4f64f0dd078926479e6c076d326 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsf.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsg.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsg.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8e48bbca743a6bdd2a2608038825613c51ec4b38 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsg.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsl.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsl.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c744b176573babaf6c706539744bd21d3eb53d63 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsl.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsl1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsl1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8b7e53848ae945398ff9dd97f6ad9ae2dbb8cd6b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsl1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsmsfi.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsmsfi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d7156aeeb198f168f744e8b1c00165ca700e1c17 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsmsfi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsmsno.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsmsno.kmx new file mode 100644 index 0000000000000000000000000000000000000000..43b8227761ba7c3f20127044fa2b49501fdaa256 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsmsno.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsn1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsn1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ac06d938dd7d1da6b2037746db3cf61b6500fbbb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsn1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsora.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsora.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5780bffad658c15edda6ea7ae90f71ddf485b72a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsora.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsorex.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsorex.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8ee12d5340b087a2e6d62111842fb3dd9570d706 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsorex.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsors1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsors1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4ffb2ac210062eafa30ae45cc8c27d0c1ef3ae9d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsors1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsp.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsp.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ddfb512ac08f0560a56cbe1508ffc9ad6505fc8c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsp.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsw.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsw.kmx new file mode 100644 index 0000000000000000000000000000000000000000..79ad8b9191bef369ccdf195eae0ef069a2198d09 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsw.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsw09.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsw09.kmx new file mode 100644 index 0000000000000000000000000000000000000000..10a92aa9fdde8e1e0c0c5567a96153f2b36e6f09 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsw09.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsyr1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsyr1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..03faa96bdef87d7bc8cbb0d9c561d8607dd92cd8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsyr1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdsyr2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdsyr2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0bb6cd7737c48c838f7196a894e56539bf8ac964 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdsyr2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtaile.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtaile.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f6965e49f32217b1423ec0993b7f4ba02aa788f6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtaile.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtajik.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtajik.kmx new file mode 100644 index 0000000000000000000000000000000000000000..34fa144e1ddab8a1c862b66913ab94bd6a660281 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtajik.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtam99.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtam99.kmx new file mode 100644 index 0000000000000000000000000000000000000000..10581a036093ce46c7027b6d240f45e9670350f8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtam99.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdth0.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdth0.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4111fffc0322fa88d432ee3a53cae74774bfa98a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdth0.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdth1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdth1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..25ebec813b0cacaf855fd1920e180402a1bf6ddb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdth1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdth2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdth2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..50e9501d624f1572be0fe8826170ff7ad7110948 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdth2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdth3.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdth3.kmx new file mode 100644 index 0000000000000000000000000000000000000000..388a30f355f7d6da912aa05256ceabe19644c969 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdth3.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtifi.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtifi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ea957fb340f6cb49b7296d2b52e5d120c28c33ab Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtifi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtifi2.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtifi2.kmx new file mode 100644 index 0000000000000000000000000000000000000000..62538f2a1aa7980c2c8ad068e7f41c2bf7b7ee28 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtifi2.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtiprd.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtiprd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3fdba0e5908435a8d8ade2cd7a0bc4106d3de931 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtiprd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtt102.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtt102.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6140e900a41bea07ee2ed062198e825269bf142a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtt102.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtuf.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtuf.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3b377481f5f410767f22302ab1e24863dd5ed641 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtuf.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtuq.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtuq.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cbd7edec80661f676770c5dac7dd892e2f794f82 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtuq.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdturme.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdturme.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e90d4804e68592fcacaf40ef6b3a377e7d830fc4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdturme.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdtzm.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdtzm.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6fa483fdd123026f0f7237a092a855f7e4825538 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdtzm.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdughr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdughr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b2cd49ec3672c0b728130660b184f30bb6eab10e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdughr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdughr1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdughr1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c15af76e8fb1a8373cc268cdda5a760718509397 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdughr1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbduk.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbduk.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4422e72bd3dfc2046830bd27368d1018f585aa45 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbduk.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdukx.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdukx.kmx new file mode 100644 index 0000000000000000000000000000000000000000..aa6a5df2dde595120b48ea7f7a20a371766770db Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdukx.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdur.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdur.kmx new file mode 100644 index 0000000000000000000000000000000000000000..79a262c7d68f7d80eee1e4c452cad29bed3e716f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdur.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdur1.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdur1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0f1831265812eccc7f88f5b3497a906f9b468146 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdur1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdurdu.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdurdu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..96270285970706cf8b5bff60e6a595849fb20dbc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdurdu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdus.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdus.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ddf9eb6bec5629bf9d8c86432c0d843bd71232b1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdus.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdusa.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdusa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..77b0662814678f80e75dbcb0ffe6eac0777a9798 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdusa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdusl.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdusl.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1866a0da59cc221891ac223007fd10011c11a321 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdusl.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdusr.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdusr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f03ab9148716777d1c96511b062193cf9a3cf5ea Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdusr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdusx.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdusx.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4f1639ebf3de2cd0f267e4c0a66ecd56f671e23e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdusx.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbduzb.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbduzb.kmx new file mode 100644 index 0000000000000000000000000000000000000000..26270dcfb3843ac380c4261bb9f32229703023f9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbduzb.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdvntc.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdvntc.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cf3c5f2bddecf79fc21e35afd1199e83bbcb81d4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdvntc.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdwol.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdwol.kmx new file mode 100644 index 0000000000000000000000000000000000000000..616dd09565d5dc2df0f71ca42a6b17293f35c3cf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdwol.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdyak.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdyak.kmx new file mode 100644 index 0000000000000000000000000000000000000000..32f30e18ba265e7a5a87b65769d7e02c59b0bf41 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdyak.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdyba.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdyba.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a30ea443abe55c1a6608ef97c34af0eb5c2081eb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdyba.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdycc.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdycc.kmx new file mode 100644 index 0000000000000000000000000000000000000000..38cdb5844bf0f70719b291bcbc79a8814e9685c8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdycc.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/basic_kbdycl.kmx b/developer/src/kmcmplib/tests/fixtures/basic_kbdycl.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b6a0c27592e3cea916ceba55467637e3cd1e2724 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/basic_kbdycl.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/batak.kmx b/developer/src/kmcmplib/tests/fixtures/batak.kmx new file mode 100644 index 0000000000000000000000000000000000000000..953244d282a6b529d84f055d9c0393afaac7a6c7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/batak.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/baybayin.kmx b/developer/src/kmcmplib/tests/fixtures/baybayin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a98eb66f7f741c35c3d684e0a415283506295070 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/baybayin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bhaiksuki_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/bhaiksuki_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..59dbfdf7b677eb64c15479c5b3d09dee4d31ed8b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bhaiksuki_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_cree_east.kmx b/developer/src/kmcmplib/tests/fixtures/bj_cree_east.kmx new file mode 100644 index 0000000000000000000000000000000000000000..db3ae952840d7387e35ba3dcfe32c16b7b05e149 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_cree_east.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_cree_east_james_bay.kmx b/developer/src/kmcmplib/tests/fixtures/bj_cree_east_james_bay.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c4ffe3262f314b79b78ad5b9d3bd0421b1c3e058 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_cree_east_james_bay.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_cree_east_latn.kmx b/developer/src/kmcmplib/tests/fixtures/bj_cree_east_latn.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f8a7734542e5ea6e5c1b6287309f35644ac683e4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_cree_east_latn.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_cree_west_latn.kmx b/developer/src/kmcmplib/tests/fixtures/bj_cree_west_latn.kmx new file mode 100644 index 0000000000000000000000000000000000000000..da25ab5de88e916913f552e2119b2c3d61c95dac Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_cree_west_latn.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_cree_woods.kmx b/developer/src/kmcmplib/tests/fixtures/bj_cree_woods.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a4da2173b7c1a740d9eb3d6333912f82cf087016 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_cree_woods.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_innu.kmx b/developer/src/kmcmplib/tests/fixtures/bj_innu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3071a9c18dc8628363d4b5883bd182908b1684d0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_innu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_innu_phonemic.kmx b/developer/src/kmcmplib/tests/fixtures/bj_innu_phonemic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fef5055f9921b55df24acb81cdf8494067814539 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_innu_phonemic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_mista_wasaha_cree.kmx b/developer/src/kmcmplib/tests/fixtures/bj_mista_wasaha_cree.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bc297ffb33ba8ad9f798dcc995525ee51e486b46 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_mista_wasaha_cree.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_naskapi_classic.kmx b/developer/src/kmcmplib/tests/fixtures/bj_naskapi_classic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3308462a43cfc2829fe65b659e944c9cb4cf8319 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_naskapi_classic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_naskapi_common.kmx b/developer/src/kmcmplib/tests/fixtures/bj_naskapi_common.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c7e3cba86992dbf8bf693db89bf26ae614611033 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_naskapi_common.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bj_oji_cree.kmx b/developer/src/kmcmplib/tests/fixtures/bj_oji_cree.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d81548c7cbce5833c925d91cc552924d857cf993 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bj_oji_cree.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/brahmi_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/brahmi_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c2a6a0210e97ad9f02bad1ac184379b96b133e63 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/brahmi_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/btl_kenya.kmx b/developer/src/kmcmplib/tests/fixtures/btl_kenya.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ce701d60552742aa52fbf0d91b86b4dcf1474085 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/btl_kenya.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/bu_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/bu_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bf5f8b54a221a6431ae78976d1711c22ac6bc42c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/bu_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/buhid.kmx b/developer/src/kmcmplib/tests/fixtures/buhid.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b379b84bb7cc0fd195e01e400fbb7a4535b64d53 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/buhid.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/burushaski_girminas.kmx b/developer/src/kmcmplib/tests/fixtures/burushaski_girminas.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e472e1e658a5cd6cde16d0bfd61f63f886423aca Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/burushaski_girminas.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/cabecar.kmx b/developer/src/kmcmplib/tests/fixtures/cabecar.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3122d53320713b7c74d33d4bb6938c8e6f520e3f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/cabecar.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/carian.kmx b/developer/src/kmcmplib/tests/fixtures/carian.kmx new file mode 100644 index 0000000000000000000000000000000000000000..28788cf0904f9fb4938e678fe4840d49ad5db040 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/carian.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/chalchiteko.kmx b/developer/src/kmcmplib/tests/fixtures/chalchiteko.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d8a7799b3b7851e202e03bd4cbdadb1d1e802971 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/chalchiteko.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/chechen_latin.kmx b/developer/src/kmcmplib/tests/fixtures/chechen_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..619a3b42ca28f22a4cf48b4e9582522920cc8142 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/chechen_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/chinuk_wawa.kmx b/developer/src/kmcmplib/tests/fixtures/chinuk_wawa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e902d3fda7795477097133c31be865e930415784 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/chinuk_wawa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/choctaw_modern.kmx b/developer/src/kmcmplib/tests/fixtures/choctaw_modern.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b995728e16734a9ec38ae36fc0457e14f88d2803 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/choctaw_modern.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/cim.kmx b/developer/src/kmcmplib/tests/fixtures/cim.kmx new file mode 100644 index 0000000000000000000000000000000000000000..25096b14a305e53fd44604a1ff9dc5e926fa4544 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/cim.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/clavbur9.kmx b/developer/src/kmcmplib/tests/fixtures/clavbur9.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3a7c6594a389ecf55e376752ca7367a3e8638bb9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/clavbur9.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/colchis_latin.kmx b/developer/src/kmcmplib/tests/fixtures/colchis_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ab7f85d3d7b2aa1b7edb3b668772f0725ae5b8ee Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/colchis_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/colchis_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/colchis_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6eadc7175738b4cfd4ce2bfbe614233c5e5dab68 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/colchis_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/common_devanagari.kmx b/developer/src/kmcmplib/tests/fixtures/common_devanagari.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ec1329475e129d8d65d917b840408b2c357f53f5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/common_devanagari.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/coptic_greek.kmx b/developer/src/kmcmplib/tests/fixtures/coptic_greek.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e380cea9530c6f1a56354f0cb33cf049071ace65 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/coptic_greek.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/coptic_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/coptic_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b65388efb15306edab1f536d33f0031c34186214 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/coptic_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/dagbani.kmx b/developer/src/kmcmplib/tests/fixtures/dagbani.kmx new file mode 100644 index 0000000000000000000000000000000000000000..31cfe3998102576fbdb4840cac412db8235d0fd3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/dagbani.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/dega.kmx b/developer/src/kmcmplib/tests/fixtures/dega.kmx new file mode 100644 index 0000000000000000000000000000000000000000..31e3373f7620d3422bf9860149e72ba7cf8d16d1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/dega.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/dene.kmx b/developer/src/kmcmplib/tests/fixtures/dene.kmx new file mode 100644 index 0000000000000000000000000000000000000000..835bbf1a6386deded575d414686f0244b16cf06c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/dene.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/deseret.kmx b/developer/src/kmcmplib/tests/fixtures/deseret.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a9f264657267b916487d671128b587793dad4e2e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/deseret.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/dogra_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/dogra_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bae47782435070bd0d7827be7732eaf648818b81 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/dogra_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/easy_chakma.kmx b/developer/src/kmcmplib/tests/fixtures/easy_chakma.kmx new file mode 100644 index 0000000000000000000000000000000000000000..df87cec7e7cadcc1278dd21a81994a93b0c8203a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/easy_chakma.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/ekwtamil99uni.kmx b/developer/src/kmcmplib/tests/fixtures/ekwtamil99uni.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5b2bf899f9faca2030272add94c56cdab52c57dc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/ekwtamil99uni.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/el_dinka.kmx b/developer/src/kmcmplib/tests/fixtures/el_dinka.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5d0983836de38f86344012fe99c0eb835bed5adc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/el_dinka.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/el_harari_latin.kmx b/developer/src/kmcmplib/tests/fixtures/el_harari_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1dd0c497b2bb3fb655ba3ea944188574be8ff49a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/el_harari_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/el_naija.kmx b/developer/src/kmcmplib/tests/fixtures/el_naija.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9a5456e2140d1e3afec1d348cbfdce888af479c5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/el_naija.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/el_nuer.kmx b/developer/src/kmcmplib/tests/fixtures/el_nuer.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1b418368fb99612d4ddc01c304b9785cf2e4b3e5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/el_nuer.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/el_pasifika.kmx b/developer/src/kmcmplib/tests/fixtures/el_pasifika.kmx new file mode 100644 index 0000000000000000000000000000000000000000..08a6cc250ea90368353cbccfb0a63e07dc3d6efa Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/el_pasifika.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/el_yolngu.kmx b/developer/src/kmcmplib/tests/fixtures/el_yolngu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0233d5c10f5117bef330618cb72f743a2db59dbe Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/el_yolngu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/embera_north.kmx b/developer/src/kmcmplib/tests/fixtures/embera_north.kmx new file mode 100644 index 0000000000000000000000000000000000000000..601a25116c877a9f3ab6c1ea0ff7086bc8511d5f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/embera_north.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/enga.kmx b/developer/src/kmcmplib/tests/fixtures/enga.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9543f557b9d4230dc4f53be848695885adacd21c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/enga.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/enggano.kmx b/developer/src/kmcmplib/tests/fixtures/enggano.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4e8ddd14db1a8bc550ce6474daa8fb5ea65c6760 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/enggano.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/english_shavian_igc.kmx b/developer/src/kmcmplib/tests/fixtures/english_shavian_igc.kmx new file mode 100644 index 0000000000000000000000000000000000000000..628d7479471acba2abec59f96b2b03062bca1ddb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/english_shavian_igc.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/english_shavian_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/english_shavian_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..92ac37c693a1eb690136d15b6c128925b9bfb65f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/english_shavian_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/engram.kmx b/developer/src/kmcmplib/tests/fixtures/engram.kmx new file mode 100644 index 0000000000000000000000000000000000000000..83f5d167f1d264bffe4d245317cd1b7c3b152471 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/engram.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/esperuni.kmx b/developer/src/kmcmplib/tests/fixtures/esperuni.kmx new file mode 100644 index 0000000000000000000000000000000000000000..093a94a107b73e0746e84e5b9b64d5befc7c2b0e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/esperuni.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/farsiman.kmx b/developer/src/kmcmplib/tests/fixtures/farsiman.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f5ac429891f5d2897a63b5a7b5ad53aa29d1ede3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/farsiman.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/finongan.kmx b/developer/src/kmcmplib/tests/fixtures/finongan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..122cd34d4562d9223a9afcde898107cfc45bb98c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/finongan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fulfulde_ajami_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/fulfulde_ajami_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9bf05cacc81564e5415893275616b25e7db8cac1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fulfulde_ajami_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fulfulde_latin_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/fulfulde_latin_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9df1ae0728213a99f413b6db1ad7cb40ba9eaebe Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fulfulde_latin_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_dakelh.kmx b/developer/src/kmcmplib/tests/fixtures/fv_dakelh.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1ab7508254240f730c718a4b75b0d0039e97d962 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_dakelh.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_dane_zaa_zaage.kmx b/developer/src/kmcmplib/tests/fixtures/fv_dane_zaa_zaage.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4f5f5c2343cb1b1c443cf504843cfc3b83a239b6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_dane_zaa_zaage.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_denesuline_epsilon.kmx b/developer/src/kmcmplib/tests/fixtures/fv_denesuline_epsilon.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a55a6f0e731ac910277eaba75290e8d587fbb59b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_denesuline_epsilon.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_diitiidatx.kmx b/developer/src/kmcmplib/tests/fixtures/fv_diitiidatx.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dfae3c8f99da1aa4cbb92dbf3462021980c21aba Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_diitiidatx.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_gitsenimx.kmx b/developer/src/kmcmplib/tests/fixtures/fv_gitsenimx.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3cf3b42f11f4f0e53005bbb04642ee58263c08b7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_gitsenimx.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_gwichin.kmx b/developer/src/kmcmplib/tests/fixtures/fv_gwichin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f99115394adcf306c53205ac9d88df600c052ea9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_gwichin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_hailzaqvla.kmx b/developer/src/kmcmplib/tests/fixtures/fv_hailzaqvla.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d39dde6a48a5b0f717a563f5620ceb8f182b8eca Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_hailzaqvla.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_haisla.kmx b/developer/src/kmcmplib/tests/fixtures/fv_haisla.kmx new file mode 100644 index 0000000000000000000000000000000000000000..90b43453b2cef92d876a25a0fd1e1817daf6ee4b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_haisla.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_halqemeylem.kmx b/developer/src/kmcmplib/tests/fixtures/fv_halqemeylem.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0572a5f9fcc56c53b1ae448d44154398fda637de Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_halqemeylem.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_han.kmx b/developer/src/kmcmplib/tests/fixtures/fv_han.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0de6f7d9226fa9aed0834bc0184c133dd0f10b2c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_han.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_henqeminem.kmx b/developer/src/kmcmplib/tests/fixtures/fv_henqeminem.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e2d4968e537c176bde029e7b45e258fec88664e3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_henqeminem.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_hlgaagilda_xaayda_kil.kmx b/developer/src/kmcmplib/tests/fixtures/fv_hlgaagilda_xaayda_kil.kmx new file mode 100644 index 0000000000000000000000000000000000000000..127e612a29259d059a634e5e661f50cb963640b5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_hlgaagilda_xaayda_kil.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_kanienkeha_e.kmx b/developer/src/kmcmplib/tests/fixtures/fv_kanienkeha_e.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cfaf38533b9a0a836c41dbd8b82d83fb406d0b67 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_kanienkeha_e.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_ktunaxa.kmx b/developer/src/kmcmplib/tests/fixtures/fv_ktunaxa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e893954de83c15c3dde7d48ceea393269965ea11 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_ktunaxa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_kwakwala.kmx b/developer/src/kmcmplib/tests/fixtures/fv_kwakwala.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d4f0f395b42eb0db6c468c4832150233e9bf9398 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_kwakwala.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_kwakwala_liqwala.kmx b/developer/src/kmcmplib/tests/fixtures/fv_kwakwala_liqwala.kmx new file mode 100644 index 0000000000000000000000000000000000000000..13444e38f321b0e7e67e217ae33e8ba83b0fa4ba Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_kwakwala_liqwala.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_migmaq.kmx b/developer/src/kmcmplib/tests/fixtures/fv_migmaq.kmx new file mode 100644 index 0000000000000000000000000000000000000000..05cab8441f0bd949a229b2f24a709b4aeab746c7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_migmaq.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_natwits.kmx b/developer/src/kmcmplib/tests/fixtures/fv_natwits.kmx new file mode 100644 index 0000000000000000000000000000000000000000..55f1f49e2b3cc67cecb8e6cbbcaebf36d5576536 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_natwits.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_nisgaa.kmx b/developer/src/kmcmplib/tests/fixtures/fv_nisgaa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4e020950bca6db5389ffa79827d784f0bfadf453 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_nisgaa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_nlekepmxcin.kmx b/developer/src/kmcmplib/tests/fixtures/fv_nlekepmxcin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c99549d94ffc9c23474c064807f6ec86057c23a2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_nlekepmxcin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_northern_tutchone.kmx b/developer/src/kmcmplib/tests/fixtures/fv_northern_tutchone.kmx new file mode 100644 index 0000000000000000000000000000000000000000..27e05e8115182ef449af96a11721d4fdcb40c5f2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_northern_tutchone.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_nsilxcen.kmx b/developer/src/kmcmplib/tests/fixtures/fv_nsilxcen.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1732ce5c3731594d1b5d2b4877d11343b35123e1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_nsilxcen.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_nuucaanul.kmx b/developer/src/kmcmplib/tests/fixtures/fv_nuucaanul.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0fa9e4ca53c46d2ee5b8e5c187d19c308ccf854a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_nuucaanul.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_secwepemctsin.kmx b/developer/src/kmcmplib/tests/fixtures/fv_secwepemctsin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c87c548e0a777de94549ec64329cbf7c18df399e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_secwepemctsin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_sencoten.kmx b/developer/src/kmcmplib/tests/fixtures/fv_sencoten.kmx new file mode 100644 index 0000000000000000000000000000000000000000..049ac7008585a3303179eac180659df286591ba0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_sencoten.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_shashishalhem.kmx b/developer/src/kmcmplib/tests/fixtures/fv_shashishalhem.kmx new file mode 100644 index 0000000000000000000000000000000000000000..200d72f3a349322ce43d6a251c50257234c7c634 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_shashishalhem.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_smalgyax.kmx b/developer/src/kmcmplib/tests/fixtures/fv_smalgyax.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cdc7b6b3be8e99ac3636a901d6763a00199528a2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_smalgyax.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_southern_tutchone.kmx b/developer/src/kmcmplib/tests/fixtures/fv_southern_tutchone.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d500f6ea9d568d3192d62125af138a3dc0ddcd67 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_southern_tutchone.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_statimcets.kmx b/developer/src/kmcmplib/tests/fixtures/fv_statimcets.kmx new file mode 100644 index 0000000000000000000000000000000000000000..012755488ab0cd35c25a664ff5798fa799cffa1d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_statimcets.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_stlatlimxec.kmx b/developer/src/kmcmplib/tests/fixtures/fv_stlatlimxec.kmx new file mode 100644 index 0000000000000000000000000000000000000000..01b8ba7bdb9e84e39d4576f13d59f3184e94d175 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_stlatlimxec.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_tagizi_dene.kmx b/developer/src/kmcmplib/tests/fixtures/fv_tagizi_dene.kmx new file mode 100644 index 0000000000000000000000000000000000000000..838054ba56178428342ee8504d724f9c0126d6bb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_tagizi_dene.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_taltan.kmx b/developer/src/kmcmplib/tests/fixtures/fv_taltan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5d7f52ce64e6329ead9cef9387cae765c6b380b4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_taltan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_tlingit.kmx b/developer/src/kmcmplib/tests/fixtures/fv_tlingit.kmx new file mode 100644 index 0000000000000000000000000000000000000000..80f13d6898224217be7d37b385db2e095ccd7f19 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_tlingit.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_tsekehne.kmx b/developer/src/kmcmplib/tests/fixtures/fv_tsekehne.kmx new file mode 100644 index 0000000000000000000000000000000000000000..277d17c7e3c2e30c25273021c3bc0656e80158f2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_tsekehne.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_tsilhqotin.kmx b/developer/src/kmcmplib/tests/fixtures/fv_tsilhqotin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..346221385782533a2c685470ffd34f39e317c435 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_tsilhqotin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_uwikala.kmx b/developer/src/kmcmplib/tests/fixtures/fv_uwikala.kmx new file mode 100644 index 0000000000000000000000000000000000000000..129819a755e08fe4285c2af889f74849724a06fc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_uwikala.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/fv_xaislakala.kmx b/developer/src/kmcmplib/tests/fixtures/fv_xaislakala.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5a98769f3bc6230d6643bd0d5dc90bceafd7394b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/fv_xaislakala.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/galaxie_greek_mnemonic.kmx b/developer/src/kmcmplib/tests/fixtures/galaxie_greek_mnemonic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..111e206752c64c8c542ab949580a76974be3be53 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/galaxie_greek_mnemonic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/galaxie_greek_positional.kmx b/developer/src/kmcmplib/tests/fixtures/galaxie_greek_positional.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dbdcfc4e41b4d7971a8abc24fc1542407f6f7aff Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/galaxie_greek_positional.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/galaxie_hebrew_mnemonic.kmx b/developer/src/kmcmplib/tests/fixtures/galaxie_hebrew_mnemonic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1773d43a20ce7aafd29af816897f3adadccece85 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/galaxie_hebrew_mnemonic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/galaxie_hebrew_positional.kmx b/developer/src/kmcmplib/tests/fixtures/galaxie_hebrew_positional.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ca089a872773c2ef123f6521394010db71754063 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/galaxie_hebrew_positional.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gandhari.kmx b/developer/src/kmcmplib/tests/fixtures/gandhari.kmx new file mode 100644 index 0000000000000000000000000000000000000000..880b46b6ed31e0ee448b2fe9315cca412feea015 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gandhari.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/geezbrhan.kmx b/developer/src/kmcmplib/tests/fixtures/geezbrhan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..57d4f37e9359609f8fa01db63a223661a30ff404 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/geezbrhan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_amh_7.kmx b/developer/src/kmcmplib/tests/fixtures/gff_amh_7.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e265cc988d7904e2d9a6777c36b1fcd98eeffd81 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_amh_7.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_amharic.kmx b/developer/src/kmcmplib/tests/fixtures/gff_amharic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ba94ba13cc3d415af322360496db419baf861570 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_amharic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_blin.kmx b/developer/src/kmcmplib/tests/fixtures/gff_blin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5c69d20dfc445dd73de9a63cbdd9877007f7cb77 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_blin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_ethiopic_7.kmx b/developer/src/kmcmplib/tests/fixtures/gff_ethiopic_7.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6dbb905de67c2428b1d13c112c953462ada8b3e5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_ethiopic_7.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_geez.kmx b/developer/src/kmcmplib/tests/fixtures/gff_geez.kmx new file mode 100644 index 0000000000000000000000000000000000000000..08cd45f84ca618d648850971fbaf712a26618c34 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_geez.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_gurage.kmx b/developer/src/kmcmplib/tests/fixtures/gff_gurage.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eb108c5d528031b73c848bcabe8ffbd73e35f6f7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_gurage.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_gurage_legacy.kmx b/developer/src/kmcmplib/tests/fixtures/gff_gurage_legacy.kmx new file mode 100644 index 0000000000000000000000000000000000000000..35456108f22df91d110264281d9d1b9d58aae34d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_gurage_legacy.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_musnad.kmx b/developer/src/kmcmplib/tests/fixtures/gff_musnad.kmx new file mode 100644 index 0000000000000000000000000000000000000000..be00b433cd84ecd44e1dcec2b0c7f285652f5e87 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_musnad.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_tigrinya_eritrea.kmx b/developer/src/kmcmplib/tests/fixtures/gff_tigrinya_eritrea.kmx new file mode 100644 index 0000000000000000000000000000000000000000..32e7202e58bff33c41c8f105a57b50ae613994e9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_tigrinya_eritrea.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gff_tigrinya_ethiopia.kmx b/developer/src/kmcmplib/tests/fixtures/gff_tigrinya_ethiopia.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e2aab809091d3a481e0972ae70f15bc67f7c8b51 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gff_tigrinya_ethiopia.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/ghana.kmx b/developer/src/kmcmplib/tests/fixtures/ghana.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5ef98ec4d8a2cb2303b506de4c98723e88ab8cd0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/ghana.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gilaki.kmx b/developer/src/kmcmplib/tests/fixtures/gilaki.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6e73cdb3007642b99f4d32edb0eddfcfd1dc9032 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gilaki.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gilaki_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/gilaki_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b6d7c24ae246cb89e146f4126601f60b84305253 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gilaki_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gondi_dev.kmx b/developer/src/kmcmplib/tests/fixtures/gondi_dev.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a11e9dbc652818d10d31a69e7390ef5f32ba3e4e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gondi_dev.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gondi_gunjala.kmx b/developer/src/kmcmplib/tests/fixtures/gondi_gunjala.kmx new file mode 100644 index 0000000000000000000000000000000000000000..40635fdec156f72101dc15b0f153154f8467c6ff Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gondi_gunjala.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/gondi_tel.kmx b/developer/src/kmcmplib/tests/fixtures/gondi_tel.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f53e419795040f7ccd55d1f92d65f9869ed0e0f9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/gondi_tel.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/greekclassical.kmx b/developer/src/kmcmplib/tests/fixtures/greekclassical.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b52d6446635a8519646b522ea71806d3f40adf17 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/greekclassical.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/hanunoo.kmx b/developer/src/kmcmplib/tests/fixtures/hanunoo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e27248f01e2fcfe720efcde8e778508f044eb0fe Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/hanunoo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/haroi.kmx b/developer/src/kmcmplib/tests/fixtures/haroi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ab97cbb1b95937c779dac0be6ed0885849d7eff3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/haroi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/hatran_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/hatran_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a9c7206c16ba3ea953d6c9693fe259e9653ed94c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/hatran_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/hausa_ajami_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/hausa_ajami_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3893c37d1245a19623d58474a1776a1d044f95b2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/hausa_ajami_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/hausa_kano.kmx b/developer/src/kmcmplib/tests/fixtures/hausa_kano.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8b670fa110fa8c59703bf693a3354ee2d8e0b789 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/hausa_kano.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/hcesar.kmx b/developer/src/kmcmplib/tests/fixtures/hcesar.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bd2ac004d673e80d7c6f675b40316bd264c02b20 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/hcesar.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/hieroglyphic.kmx b/developer/src/kmcmplib/tests/fixtures/hieroglyphic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..20e616e0e0c73f4d06299ff03f28bc97110d414d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/hieroglyphic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/himyarit_musnad.kmx b/developer/src/kmcmplib/tests/fixtures/himyarit_musnad.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8d6dd77e25fa8250c4010f55f3022e591cd17bf2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/himyarit_musnad.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/hindi_modular.kmx b/developer/src/kmcmplib/tests/fixtures/hindi_modular.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ff755dabe0a6975f4385c0ab926dab23d90b7f29 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/hindi_modular.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/indigenous_nt.kmx b/developer/src/kmcmplib/tests/fixtures/indigenous_nt.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d5c20049c17e30fe7b04a4a42a8f5b65584e87b3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/indigenous_nt.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/indonesia.kmx b/developer/src/kmcmplib/tests/fixtures/indonesia.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4141cd42785a7820c5726feafd8fc7a7338d627c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/indonesia.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/indonesian_suku.kmx b/developer/src/kmcmplib/tests/fixtures/indonesian_suku.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c7c77ad062f0b0bff7546e177585408449135a1a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/indonesian_suku.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/inuktitut_naqittaut.kmx b/developer/src/kmcmplib/tests/fixtures/inuktitut_naqittaut.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6cd4ba4462739e4b699f8baabdf360574653d27f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/inuktitut_naqittaut.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/ishkashimi_cyrillic.kmx b/developer/src/kmcmplib/tests/fixtures/ishkashimi_cyrillic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..512a576c4a39f0a295ad3d3bb1380cdcadf513fd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/ishkashimi_cyrillic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/itrans_bengali.kmx b/developer/src/kmcmplib/tests/fixtures/itrans_bengali.kmx new file mode 100644 index 0000000000000000000000000000000000000000..49103e231a450590c650734b9307208c1c4020b7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/itrans_bengali.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/itrans_devanagari_hindi.kmx b/developer/src/kmcmplib/tests/fixtures/itrans_devanagari_hindi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..69a3bed26648b58ce109c15bb496d470807ca383 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/itrans_devanagari_hindi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/itrans_devanagari_sanskrit_vedic.kmx b/developer/src/kmcmplib/tests/fixtures/itrans_devanagari_sanskrit_vedic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..06adc62f382f179e372a4196c3084770ccbe1933 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/itrans_devanagari_sanskrit_vedic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/itrans_gujarati.kmx b/developer/src/kmcmplib/tests/fixtures/itrans_gujarati.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d46598d8d257e5ae384b0f8e8f182ef4f394fff1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/itrans_gujarati.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/itrans_gurmukhi.kmx b/developer/src/kmcmplib/tests/fixtures/itrans_gurmukhi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c56a17b39c0c50d271acfe95ee76d39be392b2e9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/itrans_gurmukhi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/itrans_odia.kmx b/developer/src/kmcmplib/tests/fixtures/itrans_odia.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7cc9c171e1485322a6503a8d811cdae0d87daffa Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/itrans_odia.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/itrans_roman.kmx b/developer/src/kmcmplib/tests/fixtures/itrans_roman.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a019db3923b33f3ed246b61d0ae0ff7da93aeab0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/itrans_roman.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/jawa.kmx b/developer/src/kmcmplib/tests/fixtures/jawa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..709021f21c647106129009b114108bcbd928e303 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/jawa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/jorai.kmx b/developer/src/kmcmplib/tests/fixtures/jorai.kmx new file mode 100644 index 0000000000000000000000000000000000000000..519a4d2fab27ddd26222c317f3f5465a97291ad6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/jorai.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/karakalpak_cyrillic.kmx b/developer/src/kmcmplib/tests/fixtures/karakalpak_cyrillic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a6dc30f7d1bcccf133d83f48ffde542713763eec Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/karakalpak_cyrillic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/karakalpak_latin.kmx b/developer/src/kmcmplib/tests/fixtures/karakalpak_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..919e2ca18521f230ec17f12939094c9b6216052f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/karakalpak_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/kayan.kmx b/developer/src/kmcmplib/tests/fixtures/kayan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7aec141c66c6b5474696dad690cc7fd9a5325fa3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/kayan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/kbdsn1.kmx b/developer/src/kmcmplib/tests/fixtures/kbdsn1.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b580f1905d6c8c1ee3585a538eca9d0796335c23 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/kbdsn1.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/kharoshthi_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/kharoshthi_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a47fe866cdc0bbd1c674d771613b9ffa05c37d6e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/kharoshthi_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/khmer_advanced.kmx b/developer/src/kmcmplib/tests/fixtures/khmer_advanced.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cc95b2cca78b5d12eedb33ad5647f3aad7005eed Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/khmer_advanced.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/khmer_angkor.kmx b/developer/src/kmcmplib/tests/fixtures/khmer_angkor.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d8495d187c4ea369dfa0b608d8a630e196360f16 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/khmer_angkor.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/khojki_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/khojki_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3ace43836be93fce942070daffce2bd9f6017b67 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/khojki_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/kmhmu_2008.kmx b/developer/src/kmcmplib/tests/fixtures/kmhmu_2008.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e0b8576fa6ec6d9f360c3c96cbd8da5229a670cd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/kmhmu_2008.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/koalibrere.kmx b/developer/src/kmcmplib/tests/fixtures/koalibrere.kmx new file mode 100644 index 0000000000000000000000000000000000000000..abd7ba92100cdd3f02d3b6919b834a6b9bef3176 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/koalibrere.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/korean_rr.kmx b/developer/src/kmcmplib/tests/fixtures/korean_rr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..74057b8d43911cd0ae24229922ba290bcfd8ff9c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/korean_rr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/koreguaje.kmx b/developer/src/kmcmplib/tests/fixtures/koreguaje.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f99ac0c0a7b49efe549ff78694c15c1ed4d05b3d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/koreguaje.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/krung.kmx b/developer/src/kmcmplib/tests/fixtures/krung.kmx new file mode 100644 index 0000000000000000000000000000000000000000..596ed3f502c9365c712e83b8a30e5a7dae7aad0d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/krung.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lahu.kmx b/developer/src/kmcmplib/tests/fixtures/lahu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8d7ecec5ec27346d913aaf6067a1efbf644decfc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lahu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lamkaang.kmx b/developer/src/kmcmplib/tests/fixtures/lamkaang.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eeb73b13ae5a47337c7559305f3756762b40c3a7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lamkaang.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/landuma.kmx b/developer/src/kmcmplib/tests/fixtures/landuma.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2a106877d39f3d78b7609d4ed729e945f5129f8b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/landuma.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lao_2008_basic.kmx b/developer/src/kmcmplib/tests/fixtures/lao_2008_basic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f6a3cf52400b2a553875f4263771d9be9d724eba Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lao_2008_basic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lao_2008_rapid.kmx b/developer/src/kmcmplib/tests/fixtures/lao_2008_rapid.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7c19d841b50a447cea5207384f95f090fa3b2e03 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lao_2008_rapid.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lao_pali.kmx b/developer/src/kmcmplib/tests/fixtures/lao_pali.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f2579f0f2193969f2b03cd24a9d940cf36f15a38 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lao_pali.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lao_pali_us.kmx b/developer/src/kmcmplib/tests/fixtures/lao_pali_us.kmx new file mode 100644 index 0000000000000000000000000000000000000000..90023f2e74297898083cef88fa2f4da6d5c32b81 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lao_pali_us.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lao_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/lao_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9e7abb7f8263e8263e050e242df560292d04390d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lao_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/lazuri.kmx b/developer/src/kmcmplib/tests/fixtures/lazuri.kmx new file mode 100644 index 0000000000000000000000000000000000000000..19c9dec7358fbfb2b220083ff2f9332a380e15c1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/lazuri.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/libtralo.kmx b/developer/src/kmcmplib/tests/fixtures/libtralo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..df52a88479248b8a1304baaefa32438da74e60be Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/libtralo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/makasar_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/makasar_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b630f2a8995bf6c73173eb975bea356831555cca Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/makasar_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/malar_braille.kmx b/developer/src/kmcmplib/tests/fixtures/malar_braille.kmx new file mode 100644 index 0000000000000000000000000000000000000000..069ed73292d4953c57955c6b1bd5d1a06ac61949 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/malar_braille.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/malar_malayalam.kmx b/developer/src/kmcmplib/tests/fixtures/malar_malayalam.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b34931675b40ce95aff0e5edb7ad25f9e96384b2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/malar_malayalam.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/malar_malayalam_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/malar_malayalam_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..06984b9a682c11d4ef192705e431ef1f29e63ec0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/malar_malayalam_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/malar_tirhuta.kmx b/developer/src/kmcmplib/tests/fixtures/malar_tirhuta.kmx new file mode 100644 index 0000000000000000000000000000000000000000..de13a1a8c3ce27e10ff0f66e85973f15ad2b3173 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/malar_tirhuta.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/maltese.kmx b/developer/src/kmcmplib/tests/fixtures/maltese.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8d083c4015315bf6a363b0a851119307a78096d4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/maltese.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/mandaic_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/mandaic_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0fd9217afb99d5601c03e222c650cb624786a12d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/mandaic_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/masaram_gondi.kmx b/developer/src/kmcmplib/tests/fixtures/masaram_gondi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ecf782860c0957caa0f60da23facd581c9bfc959 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/masaram_gondi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/me_en.kmx b/developer/src/kmcmplib/tests/fixtures/me_en.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d9770fb8bb07953099881be8adb2ce582ef4e73f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/me_en.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/meitei_legacy.kmx b/developer/src/kmcmplib/tests/fixtures/meitei_legacy.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fd43336cc69f8f891cc895b891ea76efd04ba223 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/meitei_legacy.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/miluk_hanis_siuslaw.kmx b/developer/src/kmcmplib/tests/fixtures/miluk_hanis_siuslaw.kmx new file mode 100644 index 0000000000000000000000000000000000000000..42057fdfb8ff0ef4d1e9c172c4078f29a8c2b555 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/miluk_hanis_siuslaw.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/modi_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/modi_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..caf54dfe1ca0bcb2cb92235cfe15a379fe3152f5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/modi_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/mon_anonta.kmx b/developer/src/kmcmplib/tests/fixtures/mon_anonta.kmx new file mode 100644 index 0000000000000000000000000000000000000000..95edf95455a0aec0915daf6343ccaa530e7d7a48 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/mon_anonta.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/mon_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/mon_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1f8e5504d0bfb007698ae0a0df65a0e1f94e5f1a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/mon_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/mongolian_cyrillic_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/mongolian_cyrillic_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e20fee204f1f5dcf11b9cb82ba8431abdedd477c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/mongolian_cyrillic_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/mozhi_malayalam.kmx b/developer/src/kmcmplib/tests/fixtures/mozhi_malayalam.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1c0137b88ca13c9bf05997b2075c1c77ba9fe8f7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/mozhi_malayalam.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/mro_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/mro_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0c24868d1e00e08d85c61aff1a55baf284616008 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/mro_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/multani_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/multani_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..db5c54f6aa989d07a587ea53a78060b3ea0a4aff Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/multani_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/multi_pak_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/multi_pak_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0f3ebfe1c996f42da41c7a0d3af9dca54c9e7234 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/multi_pak_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/munji.kmx b/developer/src/kmcmplib/tests/fixtures/munji.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bfc51c4c8681c0822b2b94250bbcb089fe41b664 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/munji.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/myancode_san.kmx b/developer/src/kmcmplib/tests/fixtures/myancode_san.kmx new file mode 100644 index 0000000000000000000000000000000000000000..95987ef8fabe2ce1ef3a4a0c4ca8c919ef7ac927 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/myancode_san.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nabataean_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/nabataean_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f8e708fff9f7101b1698a20ee90f8f6cca16ecbe Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nabataean_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/naijatype.kmx b/developer/src/kmcmplib/tests/fixtures/naijatype.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d2345dfda7744bbecc4bad7e26d882cac87e24d4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/naijatype.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nailangs.kmx b/developer/src/kmcmplib/tests/fixtures/nailangs.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8dd07c6a088b2ba9d39ea782d652e13110def88f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nailangs.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nasa_yuwe.kmx b/developer/src/kmcmplib/tests/fixtures/nasa_yuwe.kmx new file mode 100644 index 0000000000000000000000000000000000000000..de011fdf954e454dfb6ccedc71b41031e06a20d7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nasa_yuwe.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nepali_traditional.kmx b/developer/src/kmcmplib/tests/fixtures/nepali_traditional.kmx new file mode 100644 index 0000000000000000000000000000000000000000..206a4ac6d0ccf700a5ba430958c5a4fb81d69886 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nepali_traditional.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/newa_romanized.kmx b/developer/src/kmcmplib/tests/fixtures/newa_romanized.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1b2282ae0c74050428f565f69f09e3e6a61f48fc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/newa_romanized.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/newa_traditional.kmx b/developer/src/kmcmplib/tests/fixtures/newa_traditional.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9d1bdce86df35776f040b019c3178dd6876745ed Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/newa_traditional.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nias.kmx b/developer/src/kmcmplib/tests/fixtures/nias.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d7079a039c34a89a9990cad605d6ae348bce943b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nias.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nisenan.kmx b/developer/src/kmcmplib/tests/fixtures/nisenan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a102ebd4b1c2c163d0c5358a5004c62ae42d08b9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nisenan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nko.kmx b/developer/src/kmcmplib/tests/fixtures/nko.kmx new file mode 100644 index 0000000000000000000000000000000000000000..69705f32b7467a77a723debace1709547f591d54 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nko.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nkonya.kmx b/developer/src/kmcmplib/tests/fixtures/nkonya.kmx new file mode 100644 index 0000000000000000000000000000000000000000..62812dab2755de7321afcf0520dfb83a80a66b8b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nkonya.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_bengali_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_bengali_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a99f0a6d1bf637acf6c702df81ed248de1d47226 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_bengali_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_devanagari_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_devanagari_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..894ae528cf41c25bc6c0c220103f5f222d4fbf18 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_devanagari_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_gujarati_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_gujarati_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..171939f8f03724a59ff01a55acd117d5529c7245 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_gujarati_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_gurmukhi_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_gurmukhi_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..cf966d1f791fa916c0b14c1f515eb9de2ad7c0cd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_gurmukhi_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_ipa.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_ipa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f7b1bb493e187ef9cc881ceb599c589271891546 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_ipa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_kannada_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_kannada_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3a96d7f934a88587c04b8d3d2b2669f58f1ea011 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_kannada_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_malayalam_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_malayalam_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0035303ca43f40f4b0eb8962806cb8a85962cb52 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_malayalam_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_oriya_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_oriya_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e3496b0640e231eba8e5083a7324db05f1cfc25a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_oriya_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_tamil_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_tamil_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a9d22bfdedd4ee03ba45f46c788442620f7ce4ef Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_tamil_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nlci_telugu_winscript.kmx b/developer/src/kmcmplib/tests/fixtures/nlci_telugu_winscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..176ce86e7859a924433be3eab0be33374796277f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nlci_telugu_winscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nrc_makah.kmx b/developer/src/kmcmplib/tests/fixtures/nrc_makah.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4c5dcebbd9c3c1a03f91a7d3096e764b8c9ca068 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nrc_makah.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/ntl_onekey.kmx b/developer/src/kmcmplib/tests/fixtures/ntl_onekey.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e39ae5d918a14b7ba987914169d836c6ce22e583 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/ntl_onekey.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/numanggang.kmx b/developer/src/kmcmplib/tests/fixtures/numanggang.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6064a1e7d944437e01bad463d4cd43fd63a99603 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/numanggang.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/nw_iranian_latin.kmx b/developer/src/kmcmplib/tests/fixtures/nw_iranian_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2d2b49f6839c14b0bfdd87bacd466127a47fc82e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/nw_iranian_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/o_tissi.kmx b/developer/src/kmcmplib/tests/fixtures/o_tissi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..58515ef2390e23035659b871adad1882083a481f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/o_tissi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/obolo_chwerty.kmx b/developer/src/kmcmplib/tests/fixtures/obolo_chwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..873f70b33be411657ac5c5f1632c89ffdf647f3b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/obolo_chwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/obolo_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/obolo_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7ef2dcdadbbc9162dc995a26d8db37afa18e593c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/obolo_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/old_hungarian.kmx b/developer/src/kmcmplib/tests/fixtures/old_hungarian.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ccb6ca06a48600872e28196197b76e07466f4aac Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/old_hungarian.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/old_turkic_udw21_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/old_turkic_udw21_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3be7e17688a650e0ecfcbf5de9b4d91ce114dea2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/old_turkic_udw21_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/orma.kmx b/developer/src/kmcmplib/tests/fixtures/orma.kmx new file mode 100644 index 0000000000000000000000000000000000000000..63fb4e8cc043dc9951cf743c92d2b5816a723230 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/orma.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/osage_nation.kmx b/developer/src/kmcmplib/tests/fixtures/osage_nation.kmx new file mode 100644 index 0000000000000000000000000000000000000000..69333f2e45922f0225750d6d4b12fcef9311d8b2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/osage_nation.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/osage_nation_new.kmx b/developer/src/kmcmplib/tests/fixtures/osage_nation_new.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ead429bb10378b05c455543aeaf82d3ee4cad888 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/osage_nation_new.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/otoe_missouria.kmx b/developer/src/kmcmplib/tests/fixtures/otoe_missouria.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3722c24dbf0f8b699ee2beffc5e5a9ef7af44e3e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/otoe_missouria.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/persian_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/persian_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..89620cddcddbdc1c6626574c298cba247e9f82c2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/persian_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/pid_piaroa.kmx b/developer/src/kmcmplib/tests/fixtures/pid_piaroa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4e8529646c4059e23a58ec2b655b6a01db1a277e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/pid_piaroa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/pingelap.kmx b/developer/src/kmcmplib/tests/fixtures/pingelap.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a54eab2accc03082a23dd50f30d25b19b03c5676 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/pingelap.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/postmodern_english_uk_dualstroke.kmx b/developer/src/kmcmplib/tests/fixtures/postmodern_english_uk_dualstroke.kmx new file mode 100644 index 0000000000000000000000000000000000000000..48859e2af0c9830218fc5d0c2fcf64aee376fdbd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/postmodern_english_uk_dualstroke.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/postmodern_english_uk_natural.kmx b/developer/src/kmcmplib/tests/fixtures/postmodern_english_uk_natural.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e8db651d3174033dc2ef8e57393227f998a9c736 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/postmodern_english_uk_natural.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/postmodern_english_us_dualstroke.kmx b/developer/src/kmcmplib/tests/fixtures/postmodern_english_us_dualstroke.kmx new file mode 100644 index 0000000000000000000000000000000000000000..322b9fec3b6995d690acedb7fb5cc629c6caf29c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/postmodern_english_us_dualstroke.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/postmodern_english_us_natural.kmx b/developer/src/kmcmplib/tests/fixtures/postmodern_english_us_natural.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8b96e384e099b2ef15ece8a19e705e5e2764e29e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/postmodern_english_us_natural.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/pukapuka.kmx b/developer/src/kmcmplib/tests/fixtures/pukapuka.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8c892107a46f3ce8a9876c01c4e96836c25eb8e3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/pukapuka.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/qom.kmx b/developer/src/kmcmplib/tests/fixtures/qom.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ca6f9fb41dcb37627e78d4ea94abb0a6ecac5b23 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/qom.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/quinault.kmx b/developer/src/kmcmplib/tests/fixtures/quinault.kmx new file mode 100644 index 0000000000000000000000000000000000000000..82f88cf24107c5e8573af4f269d3d9443b009da4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/quinault.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/qwerty_farang.kmx b/developer/src/kmcmplib/tests/fixtures/qwerty_farang.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8f27dd42d24beb7ee1900132fc0b91ec63feab14 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/qwerty_farang.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_aer.kmx b/developer/src/kmcmplib/tests/fixtures/rac_aer.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f32daed2596b947a13f4befee425ae21df69b17a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_aer.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_arabic.kmx b/developer/src/kmcmplib/tests/fixtures/rac_arabic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ba7ffbaa404f8e4ed72b8b254d74b1d3b74e6635 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_arabic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_balti.kmx b/developer/src/kmcmplib/tests/fixtures/rac_balti.kmx new file mode 100644 index 0000000000000000000000000000000000000000..942b98e8933ddf32b4be02fa3333404964c25a2c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_balti.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_brahui.kmx b/developer/src/kmcmplib/tests/fixtures/rac_brahui.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6a0fd1cafad6ab24a55f91479d85bd64dd0c3e48 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_brahui.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_brahui_latin.kmx b/developer/src/kmcmplib/tests/fixtures/rac_brahui_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6e63256900d63d84ec5dcbc5e03303ddda4c890d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_brahui_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_burushaski.kmx b/developer/src/kmcmplib/tests/fixtures/rac_burushaski.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3864031e7459aacb5380c5da8ed32174faed9cd4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_burushaski.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_dameli.kmx b/developer/src/kmcmplib/tests/fixtures/rac_dameli.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8eb9c3359d32ef39dff1a202046c27d7e68af230 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_dameli.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_dhatki.kmx b/developer/src/kmcmplib/tests/fixtures/rac_dhatki.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3e4abc594ae9f922a01ef0544465f7a3acd7cf96 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_dhatki.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_dogri.kmx b/developer/src/kmcmplib/tests/fixtures/rac_dogri.kmx new file mode 100644 index 0000000000000000000000000000000000000000..77345ca8a07b8f8424a733ce6e156f2fb9493855 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_dogri.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_gawar_bati.kmx b/developer/src/kmcmplib/tests/fixtures/rac_gawar_bati.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dba08659fbe937d34dd7a145c43c9b4047ad73ea Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_gawar_bati.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_gawri.kmx b/developer/src/kmcmplib/tests/fixtures/rac_gawri.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3ae6573be7cb9668b3876478b014a7c5dcac257c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_gawri.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_hazaragi.kmx b/developer/src/kmcmplib/tests/fixtures/rac_hazaragi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d24481e11719943d04f30c14897cde8bb05507a6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_hazaragi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_hindko.kmx b/developer/src/kmcmplib/tests/fixtures/rac_hindko.kmx new file mode 100644 index 0000000000000000000000000000000000000000..99453a79c50a2de81c6c48744e169efcdfccbd24 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_hindko.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_indus_kohistani.kmx b/developer/src/kmcmplib/tests/fixtures/rac_indus_kohistani.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7966cfda014a4840b835cb101ecc2e912ba1496e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_indus_kohistani.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_kalasha.kmx b/developer/src/kmcmplib/tests/fixtures/rac_kalasha.kmx new file mode 100644 index 0000000000000000000000000000000000000000..de56a3d6a8937f3e8fa7dadd7451bb669837c424 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_kalasha.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_kashmir_shina.kmx b/developer/src/kmcmplib/tests/fixtures/rac_kashmir_shina.kmx new file mode 100644 index 0000000000000000000000000000000000000000..075f85bf48fba5505452d63400c32747e4a9a6f1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_kashmir_shina.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_kashmiri.kmx b/developer/src/kmcmplib/tests/fixtures/rac_kashmiri.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f2c5ee0545011cb7c2aedd06d603622312e8f0bb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_kashmiri.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_khowar.kmx b/developer/src/kmcmplib/tests/fixtures/rac_khowar.kmx new file mode 100644 index 0000000000000000000000000000000000000000..122edb343c7257dc723821f593b4b3d17770bb9f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_khowar.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_marwari.kmx b/developer/src/kmcmplib/tests/fixtures/rac_marwari.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6144b12ccca43999f81e736e3dbb09e526791e99 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_marwari.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_munji.kmx b/developer/src/kmcmplib/tests/fixtures/rac_munji.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3714489c5b487189eed311895b58f5f1593a644d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_munji.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_oadki.kmx b/developer/src/kmcmplib/tests/fixtures/rac_oadki.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7a94331ecbb48aea40899f04f1b310d6847d416d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_oadki.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_ormuri.kmx b/developer/src/kmcmplib/tests/fixtures/rac_ormuri.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fe4dda40f07fc4f51e84c5dc238c2e7f3a2d6406 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_ormuri.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_pahari.kmx b/developer/src/kmcmplib/tests/fixtures/rac_pahari.kmx new file mode 100644 index 0000000000000000000000000000000000000000..64d842679af8197ebd744f1c0d4a9daede057faa Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_pahari.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_palula.kmx b/developer/src/kmcmplib/tests/fixtures/rac_palula.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d6a28b1843121f26034e52c18bb00c2127fa4775 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_palula.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_parkari_koli.kmx b/developer/src/kmcmplib/tests/fixtures/rac_parkari_koli.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3dd6be1d5cc3fe681029f232ef363ffbc3423945 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_parkari_koli.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_pashai.kmx b/developer/src/kmcmplib/tests/fixtures/rac_pashai.kmx new file mode 100644 index 0000000000000000000000000000000000000000..965feaf6bd1c74be79fcda793e9a70daf8da68e4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_pashai.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_pashto.kmx b/developer/src/kmcmplib/tests/fixtures/rac_pashto.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3d5bb2970f4932f1fc776781e2a554fd3b10663d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_pashto.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_saraiki.kmx b/developer/src/kmcmplib/tests/fixtures/rac_saraiki.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1cc25371ed06f48cbd4a4e64f089677ae71e68c3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_saraiki.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_shina.kmx b/developer/src/kmcmplib/tests/fixtures/rac_shina.kmx new file mode 100644 index 0000000000000000000000000000000000000000..818c4bb9e0790dfc7c3c3784360e1573412050b8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_shina.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_sindhi.kmx b/developer/src/kmcmplib/tests/fixtures/rac_sindhi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7cf18e2146d7a7e052ea746a1858a934537d1a67 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_sindhi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_torwali.kmx b/developer/src/kmcmplib/tests/fixtures/rac_torwali.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b9917e064b494f068bea8fb9e634f1fff9012705 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_torwali.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_urdu.kmx b/developer/src/kmcmplib/tests/fixtures/rac_urdu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c46a0af0e0a8262283704740e1cb9e58ead021cd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_urdu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_ushojo.kmx b/developer/src/kmcmplib/tests/fixtures/rac_ushojo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e518f79d002eaa045b00de034ea588722d78b66a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_ushojo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_uyghur.kmx b/developer/src/kmcmplib/tests/fixtures/rac_uyghur.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3bf55f93935f044d02c498e46bf1e93a309e152e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_uyghur.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_wadiyara.kmx b/developer/src/kmcmplib/tests/fixtures/rac_wadiyara.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8b1dcc69bfb24509e5a4ef9343483eecf87c9279 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_wadiyara.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_wakhi.kmx b/developer/src/kmcmplib/tests/fixtures/rac_wakhi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c3acae747f60de7830c118b2869455f5d96ec654 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_wakhi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_western_punjabi.kmx b/developer/src/kmcmplib/tests/fixtures/rac_western_punjabi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eac2a21ec01380eacd24c68a99a23fdb718be4e7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_western_punjabi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rac_yidgha.kmx b/developer/src/kmcmplib/tests/fixtures/rac_yidgha.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5d777ce16c22245b1adfbac9398a7d5a5bf5e792 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rac_yidgha.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rawang.kmx b/developer/src/kmcmplib/tests/fixtures/rawang.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5ef43d22be467fcae7f86acfb85e2bfca0b4c192 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rawang.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rejang.kmx b/developer/src/kmcmplib/tests/fixtures/rejang.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c04ff065e2c4fecaaf16bbac394a805adcd326c6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rejang.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/remington_gail.kmx b/developer/src/kmcmplib/tests/fixtures/remington_gail.kmx new file mode 100644 index 0000000000000000000000000000000000000000..16412933b6f09c949dc090c773037d03b64059a4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/remington_gail.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rohingya_arab.kmx b/developer/src/kmcmplib/tests/fixtures/rohingya_arab.kmx new file mode 100644 index 0000000000000000000000000000000000000000..07e61629b5e5a77cb9447deaaf46c32aa67a0387 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rohingya_arab.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/rossel.kmx b/developer/src/kmcmplib/tests/fixtures/rossel.kmx new file mode 100644 index 0000000000000000000000000000000000000000..98bca0b9464cd808441242cf418896c3f9d1b0c6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/rossel.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/runeboard.kmx b/developer/src/kmcmplib/tests/fixtures/runeboard.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d41acc4124a158b91a799a7b8986cd04c85cc942 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/runeboard.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/russian_mnemonic_r.kmx b/developer/src/kmcmplib/tests/fixtures/russian_mnemonic_r.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e9a99d02db29ac2a1e6b21511f1d406d14e64576 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/russian_mnemonic_r.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sabdalipi_assamese.kmx b/developer/src/kmcmplib/tests/fixtures/sabdalipi_assamese.kmx new file mode 100644 index 0000000000000000000000000000000000000000..1b7f80b8b13135fa8b4b90783404de82bfa6114c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sabdalipi_assamese.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sahaptin_umatilla.kmx b/developer/src/kmcmplib/tests/fixtures/sahaptin_umatilla.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bfac93d7e6e6bbc5fd45adaf44084fec2f87d5f4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sahaptin_umatilla.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sahaptin_yakima.kmx b/developer/src/kmcmplib/tests/fixtures/sahaptin_yakima.kmx new file mode 100644 index 0000000000000000000000000000000000000000..53d610e7e743131cb2b30f8d84ac62734334e045 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sahaptin_yakima.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sanjha_punjabi.kmx b/developer/src/kmcmplib/tests/fixtures/sanjha_punjabi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..739d01869397bfd75b556a5bb89e77eaef8c76fc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sanjha_punjabi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/santali_latin.kmx b/developer/src/kmcmplib/tests/fixtures/santali_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5a0756301cc95f11feb352d114b22d3191296c33 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/santali_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/saraiki.kmx b/developer/src/kmcmplib/tests/fixtures/saraiki.kmx new file mode 100644 index 0000000000000000000000000000000000000000..260e96f5ca778e5ffd784bf784c06fe3ea402e2c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/saraiki.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/satere.kmx b/developer/src/kmcmplib/tests/fixtures/satere.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e9af31938826265a6f8f3c9e70538ae4748d8ab0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/satere.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/shahmukhi_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/shahmukhi_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0d8cdb54f77be275dbe5e144b0b15ba9590aaa29 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/shahmukhi_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/shan.kmx b/developer/src/kmcmplib/tests/fixtures/shan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d84a72e3ee815867d64e6e10d2f021112be65bfb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/shan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/shaw_2layer.kmx b/developer/src/kmcmplib/tests/fixtures/shaw_2layer.kmx new file mode 100644 index 0000000000000000000000000000000000000000..87cd30ad34a3ef5fc400a62c8794ebde209e7690 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/shaw_2layer.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/siddham_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/siddham_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0f139602947659ba0cec79f6e37752ba845ecae0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/siddham_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_akha_act.kmx b/developer/src/kmcmplib/tests/fixtures/sil_akha_act.kmx new file mode 100644 index 0000000000000000000000000000000000000000..6a81a33d8b49cde3dbcd7601e54d93abe71b42bc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_akha_act.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_arabic_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_arabic_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4caa43ac6410c7803a2dae8cb3b4284ed9e44a27 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_arabic_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_areare.kmx b/developer/src/kmcmplib/tests/fixtures/sil_areare.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8ffe02d000f21ba7ca0e7a7e5229169dddc73987 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_areare.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_bari.kmx b/developer/src/kmcmplib/tests/fixtures/sil_bari.kmx new file mode 100644 index 0000000000000000000000000000000000000000..639e50e028e82135e3a0992f2567ea7395e396b8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_bari.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_bengali_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_bengali_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dae551bdbd1ccd955b3e366a6d92fe5912e51ea2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_bengali_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_bolivia.kmx b/developer/src/kmcmplib/tests/fixtures/sil_bolivia.kmx new file mode 100644 index 0000000000000000000000000000000000000000..75cf86a81df962956a5c746241cce26c90deca02 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_bolivia.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_boonkit.kmx b/developer/src/kmcmplib/tests/fixtures/sil_boonkit.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dfd184f1ab4c9d170cecd1039fab0aa051a265f8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_boonkit.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_brao.kmx b/developer/src/kmcmplib/tests/fixtures/sil_brao.kmx new file mode 100644 index 0000000000000000000000000000000000000000..80d140b65a28b8c2c2120e686a77b787444fbf42 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_brao.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_bru.kmx b/developer/src/kmcmplib/tests/fixtures/sil_bru.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0bb31ea045bec7b946d4bd4b7b8bc04819dccc2d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_bru.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_buang.kmx b/developer/src/kmcmplib/tests/fixtures/sil_buang.kmx new file mode 100644 index 0000000000000000000000000000000000000000..288f2fb7fb7e862229b9d1520d8cc63b0ba99297 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_buang.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_bunong.kmx b/developer/src/kmcmplib/tests/fixtures/sil_bunong.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7eeaf731e1c7bc8cad1018d956c556ed2474e1bb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_bunong.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_busa.kmx b/developer/src/kmcmplib/tests/fixtures/sil_busa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4e907fa2f25088163584b9f2c31901a0c93f681e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_busa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_bwe_karen.kmx b/developer/src/kmcmplib/tests/fixtures/sil_bwe_karen.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8fb25d32a672e15de8c31b2c1758f56e6dd90e99 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_bwe_karen.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_cameroon_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_cameroon_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..da7f23d2d02fccb73ec655da2b38f85359483f4b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_cameroon_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_cameroon_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_cameroon_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0e3bf67607d2cd58b666b905afd2cb432060b55a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_cameroon_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_cherokee_nation.kmx b/developer/src/kmcmplib/tests/fixtures/sil_cherokee_nation.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c568a85e0593e5a72914edd7fddbd97e990fb60b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_cherokee_nation.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_cheyenne.kmx b/developer/src/kmcmplib/tests/fixtures/sil_cheyenne.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0fef098219c522cfac894926df2e8280b82d02d3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_cheyenne.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_cipher_music.kmx b/developer/src/kmcmplib/tests/fixtures/sil_cipher_music.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f1eda8ec037084236280f625a52c9e565cfc6b38 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_cipher_music.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_devanagari_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_devanagari_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f4a4a85f62eabb51c48da4eb39a5c6d76455ce3c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_devanagari_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_devanagari_romanized.kmx b/developer/src/kmcmplib/tests/fixtures/sil_devanagari_romanized.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dbb114e0c97a85c1c921f9b631b1445d519cf784 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_devanagari_romanized.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_devanagari_typewriter.kmx b/developer/src/kmcmplib/tests/fixtures/sil_devanagari_typewriter.kmx new file mode 100644 index 0000000000000000000000000000000000000000..38dbb8008575750b2f51afc7bbaf7eca4a8afee2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_devanagari_typewriter.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_dzongkha.kmx b/developer/src/kmcmplib/tests/fixtures/sil_dzongkha.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d0a824cec8b97802b572a3cdabb58fb36eaaeae0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_dzongkha.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_eastern_congo.kmx b/developer/src/kmcmplib/tests/fixtures/sil_eastern_congo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7d604831fbeef3c34e6aa02dc4d63c33a349109c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_eastern_congo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_el_ethiopian_latin.kmx b/developer/src/kmcmplib/tests/fixtures/sil_el_ethiopian_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..67834cb25c3f1ff716064e804de91f78615a9f0a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_el_ethiopian_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_ethiopic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_ethiopic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3433f5c103b686d4fb258fc56b499f9cc8340fb6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_ethiopic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_ethiopic_power_g.kmx b/developer/src/kmcmplib/tests/fixtures/sil_ethiopic_power_g.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ce697e4e16984959b5c4c37eacfd502daf1c9a5a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_ethiopic_power_g.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_euro_latin.kmx b/developer/src/kmcmplib/tests/fixtures/sil_euro_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..60973192d778367acd633c7a9f2995a57bc64ffe Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_euro_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_extended_urdu_np.kmx b/developer/src/kmcmplib/tests/fixtures/sil_extended_urdu_np.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3dd06bd052011e7511d1b54f8a8e4e60f0f72c45 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_extended_urdu_np.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_greek_polytonic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_greek_polytonic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..904fdeea2b7aeebcd084722787741445a1731ed0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_greek_polytonic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_hawaiian.kmx b/developer/src/kmcmplib/tests/fixtures/sil_hawaiian.kmx new file mode 100644 index 0000000000000000000000000000000000000000..74b83ca88a69defbe7f6d94047a6073f53247fac Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_hawaiian.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_hebr_grek_trans.kmx b/developer/src/kmcmplib/tests/fixtures/sil_hebr_grek_trans.kmx new file mode 100644 index 0000000000000000000000000000000000000000..77128fbd01e4677e05ebfdf11d62a53aa6231e99 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_hebr_grek_trans.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_hebrew.kmx b/developer/src/kmcmplib/tests/fixtures/sil_hebrew.kmx new file mode 100644 index 0000000000000000000000000000000000000000..18163f9a14acaad09e9049233967f3b7a3cc1784 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_hebrew.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_hebrew_legacy.kmx b/developer/src/kmcmplib/tests/fixtures/sil_hebrew_legacy.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0a8646d8ec070edea412ff3a1cd5ed5410d9d8ad Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_hebrew_legacy.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_hmd_plrd.kmx b/developer/src/kmcmplib/tests/fixtures/sil_hmd_plrd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b39614c21337458bb6df0bdd6d9be4eb20ee5804 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_hmd_plrd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_indic_roman.kmx b/developer/src/kmcmplib/tests/fixtures/sil_indic_roman.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f41b2cc8b3c88c94721993ad8a486f11b087e4eb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_indic_roman.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_ipa.kmx b/developer/src/kmcmplib/tests/fixtures/sil_ipa.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8d4d9d97e019248a37ad9f39674439a4ef3bbd2c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_ipa.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_jarai.kmx b/developer/src/kmcmplib/tests/fixtures/sil_jarai.kmx new file mode 100644 index 0000000000000000000000000000000000000000..90cc3a418d7af01bf19060d94fc8e3c3c5983970 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_jarai.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_kayah_kali.kmx b/developer/src/kmcmplib/tests/fixtures/sil_kayah_kali.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a4214e1dfc88238c0607aad8adccc4da05b625f1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_kayah_kali.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_kayah_latn.kmx b/developer/src/kmcmplib/tests/fixtures/sil_kayah_latn.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5ab026b835f8a0de082f4b8b0059e993fd054560 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_kayah_latn.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_kayah_mymr.kmx b/developer/src/kmcmplib/tests/fixtures/sil_kayah_mymr.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e918e45b0cf87dbb66f838c70368ab6874fdc5bf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_kayah_mymr.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_khamti.kmx b/developer/src/kmcmplib/tests/fixtures/sil_khamti.kmx new file mode 100644 index 0000000000000000000000000000000000000000..52ed2dc0e3343ad197758490f6b85362626ade95 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_khamti.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_khmer.kmx b/developer/src/kmcmplib/tests/fixtures/sil_khmer.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c53eb704f1b76c2c07ad391bb17287b212f494e9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_khmer.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_khowar.kmx b/developer/src/kmcmplib/tests/fixtures/sil_khowar.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8cd336d8e4359e029999c0dca4bab35f17c2d81f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_khowar.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_kmhmu.kmx b/developer/src/kmcmplib/tests/fixtures/sil_kmhmu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..630c36cb3db0d08c0792a4fdf714bfd27b0d2093 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_kmhmu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_korda_jamo.kmx b/developer/src/kmcmplib/tests/fixtures/sil_korda_jamo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c03f35d313c301379d34d05e2aed8c4ca8d03b61 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_korda_jamo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_korda_latin.kmx b/developer/src/kmcmplib/tests/fixtures/sil_korda_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e9f48e301300a9258e65296decc80fd1e5e9d90f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_korda_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_korean_morse.kmx b/developer/src/kmcmplib/tests/fixtures/sil_korean_morse.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e2adba2aca2f0d0cf33a488e0e3a683b9898abec Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_korean_morse.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_kvl_kayaw.kmx b/developer/src/kmcmplib/tests/fixtures/sil_kvl_kayaw.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4dedd718537edbf1bca1e0174af80f4cf59e63dc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_kvl_kayaw.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_lepcha.kmx b/developer/src/kmcmplib/tests/fixtures/sil_lepcha.kmx new file mode 100644 index 0000000000000000000000000000000000000000..663bf4580e7fef1b574ad1798343067e20536433 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_lepcha.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_limbu_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_limbu_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..58ecb1a522654d1cad07881fd44b271bd7fd22ae Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_limbu_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_limbu_typewriter.kmx b/developer/src/kmcmplib/tests/fixtures/sil_limbu_typewriter.kmx new file mode 100644 index 0000000000000000000000000000000000000000..651bcbd28e83e827b04489db2b3788cc959c1a9d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_limbu_typewriter.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_lisu_basic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_lisu_basic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d85fadca1cc584913b4f300f8a7beb8c136ec032 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_lisu_basic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_lisu_standard.kmx b/developer/src/kmcmplib/tests/fixtures/sil_lisu_standard.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4eee9a9104c5e8d3855739d7a41685d84eeaf77d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_lisu_standard.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_lpo_plrd.kmx b/developer/src/kmcmplib/tests/fixtures/sil_lpo_plrd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..616799187aded941742991fea1afc1379275eff8 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_lpo_plrd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_madi.kmx b/developer/src/kmcmplib/tests/fixtures/sil_madi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d92aff331b7fb8d5c10702e41289b5a01dba8d97 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_madi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_makuri.kmx b/developer/src/kmcmplib/tests/fixtures/sil_makuri.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eec4b8b1b73f6ef0aeed01fd9c22b2b5ff317bf2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_makuri.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_mali_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_mali_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..84dd3f53d29dc2c5df805321780b5d44d9df9893 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_mali_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_mali_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_mali_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..29e170f6e6b856e48104699304d34a967ff19abd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_mali_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_mali_qwertz.kmx b/developer/src/kmcmplib/tests/fixtures/sil_mali_qwertz.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b5bd3413865538a189d8abf1b29d6a7d03578db6 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_mali_qwertz.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_moore.kmx b/developer/src/kmcmplib/tests/fixtures/sil_moore.kmx new file mode 100644 index 0000000000000000000000000000000000000000..72e3778d5e0fe59247192510bc40fd6d3b541099 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_moore.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_myanmar_my3.kmx b/developer/src/kmcmplib/tests/fixtures/sil_myanmar_my3.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ad1cb863a99d36774764967e7e033b82b6870fed Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_myanmar_my3.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_myanmar_mywinext.kmx b/developer/src/kmcmplib/tests/fixtures/sil_myanmar_mywinext.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d19b8ecdb53be4ca8f3f2d85385581a08eb9160f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_myanmar_mywinext.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_nigeria_dot.kmx b/developer/src/kmcmplib/tests/fixtures/sil_nigeria_dot.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d15171d8a1ee75b810d7423b9969e5797aa1320b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_nigeria_dot.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_nigeria_odd_vowels.kmx b/developer/src/kmcmplib/tests/fixtures/sil_nigeria_odd_vowels.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f6d6b9cb0970910d30d028e0fc5664915706ffcf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_nigeria_odd_vowels.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_nigeria_underline.kmx b/developer/src/kmcmplib/tests/fixtures/sil_nigeria_underline.kmx new file mode 100644 index 0000000000000000000000000000000000000000..adb38082b23ea4709b27103651d7fd4d251c2b8a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_nigeria_underline.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_nko.kmx b/developer/src/kmcmplib/tests/fixtures/sil_nko.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5616c8bb5888394246ca02efcdc7325549fdb4cc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_nko.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_nubian.kmx b/developer/src/kmcmplib/tests/fixtures/sil_nubian.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bc178a0659b868841363a80ffe3ba73de23ff4c7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_nubian.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_pan_africa_mnemonic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_pan_africa_mnemonic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..dd3551d2bad7fbaa2e8854eaa3991e7adeac1faf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_pan_africa_mnemonic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_pan_africa_positional.kmx b/developer/src/kmcmplib/tests/fixtures/sil_pan_africa_positional.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ab7eb053d9d0ad9c65ccf1d2e15e4df3531847b9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_pan_africa_positional.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_philippines.kmx b/developer/src/kmcmplib/tests/fixtures/sil_philippines.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fd5db7d4f4721bc2cd656f64895f40504c7d929a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_philippines.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_sahu.kmx b/developer/src/kmcmplib/tests/fixtures/sil_sahu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e5548549a7b9ad70c5cb5f53fa0fd0b5d948a323 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_sahu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_bsc_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_bsc_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b7162c461ff023be25aa99f50d76413bb1d9ea4a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_bsc_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_cou_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_cou_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b74e2888f219f35d0571acc3f736ee382f6d49b1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_cou_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_dyo_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_dyo_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..91de009800efe678f5250f1ce4d6604f13f38692 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_dyo_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_gsl_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_gsl_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8db0110549ab5c6b21f9ac830358e6a2cfd529ed Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_gsl_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_krx_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_krx_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..74ec159fb0d228cb9b75b9558c0bd6e769e5d736 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_krx_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_ndv_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_ndv_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0afef1c629ba71650c6b0de5531ef920bdceb51f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_ndv_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_sav_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_sav_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..bfc3da4321e228bc89cb7b1c5844284f3811dd62 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_sav_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_snf_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_snf_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..69f9a2a06742bfb5ac21db819963368a49593af1 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_snf_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_srr_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_srr_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2d1eea7adee598daca7daafcc3e08b8da332f165 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_srr_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_senegal_wo_azerty.kmx b/developer/src/kmcmplib/tests/fixtures/sil_senegal_wo_azerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c041de1fce019dfa3e1a34fcc298eeb4fbca4d4a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_senegal_wo_azerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_sgaw_karen.kmx b/developer/src/kmcmplib/tests/fixtures/sil_sgaw_karen.kmx new file mode 100644 index 0000000000000000000000000000000000000000..96212bf1b295c9454719ae25228616ec3c3a1c78 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_sgaw_karen.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_shan.kmx b/developer/src/kmcmplib/tests/fixtures/sil_shan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..35a91760f2d4c44bbe95acc0ea48e939a51bd822 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_shan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tai_dam.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fe7dd8513ce439d356aa6b1a3f5f73c5cfe3fa98 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_lao.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_lao.kmx new file mode 100644 index 0000000000000000000000000000000000000000..9e400619ea30b2ef659929f2b1f1bf0b8f38bc78 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_lao.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_latin.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e05aa9b5c1335fb2e249aa8dbc308fe7f942ae78 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_typewriter.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_typewriter.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7db476799ff3ad24c81f3308edb693b4079ca9e7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tai_dam_typewriter.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tawallammat.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tawallammat.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f863586f92a5978b841387fbf58167a4c5412a4a Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tawallammat.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tchad.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tchad.kmx new file mode 100644 index 0000000000000000000000000000000000000000..19802d37264e2025a174e9c101c6c90925316c9d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tchad.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tepehuan.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tepehuan.kmx new file mode 100644 index 0000000000000000000000000000000000000000..2a591d64631b22b461893275f80379f07fe1f780 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tepehuan.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_torwali.kmx b/developer/src/kmcmplib/tests/fixtures/sil_torwali.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c31bd27e433574ce77d26a400c586c3ee2766e1b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_torwali.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_tunisian.kmx b/developer/src/kmcmplib/tests/fixtures/sil_tunisian.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ff3d6abdf02cb3b9ac1ab38bcc35ed21bd18e5fc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_tunisian.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_uganda_tanzania.kmx b/developer/src/kmcmplib/tests/fixtures/sil_uganda_tanzania.kmx new file mode 100644 index 0000000000000000000000000000000000000000..852f028d5175d1d1fb12e7b19e99a70d45e402be Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_uganda_tanzania.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_vai.kmx b/developer/src/kmcmplib/tests/fixtures/sil_vai.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eac0c3ff1e9343f9ce45660d5da547f8239e273d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_vai.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_wayuu.kmx b/developer/src/kmcmplib/tests/fixtures/sil_wayuu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a3a2499d0d369b245e1f9db525a431fc1e2c217d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_wayuu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_ygp_plrd.kmx b/developer/src/kmcmplib/tests/fixtures/sil_ygp_plrd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ff801a19bb893cca42390a936bfe2f799a40c9ec Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_ygp_plrd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_yi.kmx b/developer/src/kmcmplib/tests/fixtures/sil_yi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c4bb0ad3ea065c0bc3d6607647b67f8a5c9873a0 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_yi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_yna_plrd.kmx b/developer/src/kmcmplib/tests/fixtures/sil_yna_plrd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e37835c6ed0d02bb7dcf573d99c5562b070d354b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_yna_plrd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_yoruba8.kmx b/developer/src/kmcmplib/tests/fixtures/sil_yoruba8.kmx new file mode 100644 index 0000000000000000000000000000000000000000..eee1e94330afd297708c62067c1603ef0ea9fe6c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_yoruba8.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_yoruba_bar.kmx b/developer/src/kmcmplib/tests/fixtures/sil_yoruba_bar.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e3c2b997995379ddc7a8a996104139dea24cab08 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_yoruba_bar.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_yoruba_dot.kmx b/developer/src/kmcmplib/tests/fixtures/sil_yoruba_dot.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b9aadb35b9443407e1c3fed290496129ed568cbd Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_yoruba_dot.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_yupik_cyrillic.kmx b/developer/src/kmcmplib/tests/fixtures/sil_yupik_cyrillic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..e804035650d537fc0e3af7e625ba0608a0aee43f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_yupik_cyrillic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_yupik_cyrillic_ru.kmx b/developer/src/kmcmplib/tests/fixtures/sil_yupik_cyrillic_ru.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d404a12d71c09a73e0aca6ee6a0cbae28a2738e9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_yupik_cyrillic_ru.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sil_ywq_plrd.kmx b/developer/src/kmcmplib/tests/fixtures/sil_ywq_plrd.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a9d75854a331bb82c471a28c4fc773bcc9c8b117 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sil_ywq_plrd.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/slc_saliba.kmx b/developer/src/kmcmplib/tests/fixtures/slc_saliba.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b74127fa0cbdc6aa5b4faf04d444928a05f2f112 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/slc_saliba.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/soqotri_arabic.kmx b/developer/src/kmcmplib/tests/fixtures/soqotri_arabic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..25955c6bdb49528d398b369b39d6d9f74bebf750 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/soqotri_arabic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/srr_ajami_qwerty.kmx b/developer/src/kmcmplib/tests/fixtures/srr_ajami_qwerty.kmx new file mode 100644 index 0000000000000000000000000000000000000000..12b4230ab9650314389c92eb773b5dac06257482 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/srr_ajami_qwerty.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sundanese.kmx b/developer/src/kmcmplib/tests/fixtures/sundanese.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d1ed7f30bb2c79edf881d63a8ba66932fe5a7a26 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sundanese.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sundanese_latin.kmx b/developer/src/kmcmplib/tests/fixtures/sundanese_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0b4a82916acfdeaf07271a68d90c53f1266dd725 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sundanese_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/swanalekha_malayalam.kmx b/developer/src/kmcmplib/tests/fixtures/swanalekha_malayalam.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0becf6aa5cd34d1d24b8722093f30445c9d0379f Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/swanalekha_malayalam.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sxava.kmx b/developer/src/kmcmplib/tests/fixtures/sxava.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7a4d83475697630c6573ed49ab11507fca4ec088 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sxava.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sxava_eo.kmx b/developer/src/kmcmplib/tests/fixtures/sxava_eo.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3023034630e2a8a40bfa0d85116a56385b519819 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sxava_eo.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/sylheti_nagri.kmx b/developer/src/kmcmplib/tests/fixtures/sylheti_nagri.kmx new file mode 100644 index 0000000000000000000000000000000000000000..81b39c7d475ea1acea0b162fac839134631438e9 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/sylheti_nagri.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/syriac_arabic.kmx b/developer/src/kmcmplib/tests/fixtures/syriac_arabic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a35c4a6663a2cab045a3bf6aa3469752ef78a563 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/syriac_arabic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/syriac_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/syriac_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..057cadf299790ce7e8ea871683e8fdff8723a7a5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/syriac_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tagbanwa_inscript.kmx b/developer/src/kmcmplib/tests/fixtures/tagbanwa_inscript.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ad8f6e992f64cc4561042232a0478d55c01a4b12 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tagbanwa_inscript.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/taigi_poj.kmx b/developer/src/kmcmplib/tests/fixtures/taigi_poj.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f0266317fb413dddd8d485bffe9e5519befa8955 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/taigi_poj.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tainua.kmx b/developer/src/kmcmplib/tests/fixtures/tainua.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a7c5302597f8ed0effa0313ad0f15fb3b01f53bf Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tainua.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tangsa_lakhum.kmx b/developer/src/kmcmplib/tests/fixtures/tangsa_lakhum.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f92abaad901dec4ac4fee457acb06898a8e0dade Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tangsa_lakhum.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tawallammat_latin.kmx b/developer/src/kmcmplib/tests/fixtures/tawallammat_latin.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4ffcea47677876fd78de071d4505017419633ce4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tawallammat_latin.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/teggargrent_lat.kmx b/developer/src/kmcmplib/tests/fixtures/teggargrent_lat.kmx new file mode 100644 index 0000000000000000000000000000000000000000..30988061fb57ed33cf2cbe4242ecf3d4b32618fb Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/teggargrent_lat.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tem_kdh.kmx b/developer/src/kmcmplib/tests/fixtures/tem_kdh.kmx new file mode 100644 index 0000000000000000000000000000000000000000..78e7b891b8ef78cd46d1d55ac24d2efdd90f7418 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tem_kdh.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/thamizha_anjal_paangu.kmx b/developer/src/kmcmplib/tests/fixtures/thamizha_anjal_paangu.kmx new file mode 100644 index 0000000000000000000000000000000000000000..5cef67f7a97ea534b8eab41ea69a356e9d0f7b17 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/thamizha_anjal_paangu.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/thamizha_bamini.kmx b/developer/src/kmcmplib/tests/fixtures/thamizha_bamini.kmx new file mode 100644 index 0000000000000000000000000000000000000000..13b6655801102ad5e2854f1a7e4c64ab9747b545 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/thamizha_bamini.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/thamizha_new_typewriter.kmx b/developer/src/kmcmplib/tests/fixtures/thamizha_new_typewriter.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0213650e6a946c64a78bd0593a8c5e8b82524db2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/thamizha_new_typewriter.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/thamizha_tamil99_ext.kmx b/developer/src/kmcmplib/tests/fixtures/thamizha_tamil99_ext.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fc6a07a9c2fc770f5c4798a0f277948d474bfb65 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/thamizha_tamil99_ext.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tibetan_direct_input.kmx b/developer/src/kmcmplib/tests/fixtures/tibetan_direct_input.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d13c37c692582ed4b0dd07c4183fc1bf460f80c3 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tibetan_direct_input.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tibetan_ewts.kmx b/developer/src/kmcmplib/tests/fixtures/tibetan_ewts.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3db3c74b93494474af41b3d83692c676914fd476 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tibetan_ewts.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tirhuta.kmx b/developer/src/kmcmplib/tests/fixtures/tirhuta.kmx new file mode 100644 index 0000000000000000000000000000000000000000..722eacc10b64adff6f00cc309a90ddb5f366db74 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tirhuta.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tlahuica.kmx b/developer/src/kmcmplib/tests/fixtures/tlahuica.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c2a4aa4a8f301504e12633543d8bf86fbcecfc95 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tlahuica.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tsakonian.kmx b/developer/src/kmcmplib/tests/fixtures/tsakonian.kmx new file mode 100644 index 0000000000000000000000000000000000000000..d2530e34be4c0c6379bf18850502bb3c41ef3dc2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tsakonian.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/tuareg_tifinagh.kmx b/developer/src/kmcmplib/tests/fixtures/tuareg_tifinagh.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a007e67e5528ba90b1b410f5c0cc3ed4b7a02bb4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/tuareg_tifinagh.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/turkmen_cyrl.kmx b/developer/src/kmcmplib/tests/fixtures/turkmen_cyrl.kmx new file mode 100644 index 0000000000000000000000000000000000000000..805865a77f96af2bc7b0cfd8a38d5053ec205d47 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/turkmen_cyrl.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/txo_toto.kmx b/developer/src/kmcmplib/tests/fixtures/txo_toto.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f54ba9b1ef43379d7070c4a2682e37243d7f79ce Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/txo_toto.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/udi_keyboard.kmx b/developer/src/kmcmplib/tests/fixtures/udi_keyboard.kmx new file mode 100644 index 0000000000000000000000000000000000000000..0312e80010d26c82f8f129644b791240b94b88b2 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/udi_keyboard.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/ukwuani.kmx b/developer/src/kmcmplib/tests/fixtures/ukwuani.kmx new file mode 100644 index 0000000000000000000000000000000000000000..94f0349856314f787bf869d174893bdfe5ed4b3b Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/ukwuani.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/uma_graphic.kmx b/developer/src/kmcmplib/tests/fixtures/uma_graphic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..a19a27489e3a3e7ed4ab546468c6b77e9f9be5b7 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/uma_graphic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/uma_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/uma_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..74bcef0a5d0782eefcb75247519d14f7bfe02617 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/uma_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/urdu_phonetic.kmx b/developer/src/kmcmplib/tests/fixtures/urdu_phonetic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..34cf644632d4c5ae7a3c586c6e77da961da790ca Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/urdu_phonetic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/urdu_phonetic_crulp.kmx b/developer/src/kmcmplib/tests/fixtures/urdu_phonetic_crulp.kmx new file mode 100644 index 0000000000000000000000000000000000000000..ecdc3419be5f6a7f96e3ba60420346969226a88c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/urdu_phonetic_crulp.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/venetia_et_histria.kmx b/developer/src/kmcmplib/tests/fixtures/venetia_et_histria.kmx new file mode 100644 index 0000000000000000000000000000000000000000..277314fd88e903b77de07733d31cb38a7f51ff70 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/venetia_et_histria.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/vm_tamil_modular.kmx b/developer/src/kmcmplib/tests/fixtures/vm_tamil_modular.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3afbbac8ee54484304e11e98a45b36893ae9bee4 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/vm_tamil_modular.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/vm_tamil_typewriter.kmx b/developer/src/kmcmplib/tests/fixtures/vm_tamil_typewriter.kmx new file mode 100644 index 0000000000000000000000000000000000000000..c93a9b5f2bff06a4397274a95d3c8d7133fa2521 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/vm_tamil_typewriter.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/wakhi_anglicized.kmx b/developer/src/kmcmplib/tests/fixtures/wakhi_anglicized.kmx new file mode 100644 index 0000000000000000000000000000000000000000..8ff5d267c9074e8fa1ded4c9a5cd76b89dfae6bc Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/wakhi_anglicized.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/wakhi_cyrillic.kmx b/developer/src/kmcmplib/tests/fixtures/wakhi_cyrillic.kmx new file mode 100644 index 0000000000000000000000000000000000000000..fd86f63d25e71ad07f86c0c4315d55b912f80fba Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/wakhi_cyrillic.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/wakhi_standard.kmx b/developer/src/kmcmplib/tests/fixtures/wakhi_standard.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4ceb2540adc9e0d4110d38c0fa1c092255a5f58d Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/wakhi_standard.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/wancho.kmx b/developer/src/kmcmplib/tests/fixtures/wancho.kmx new file mode 100644 index 0000000000000000000000000000000000000000..68ab51c6e968cc753c8a76ee18bca6e0f9053b69 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/wancho.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/warang_citi.kmx b/developer/src/kmcmplib/tests/fixtures/warang_citi.kmx new file mode 100644 index 0000000000000000000000000000000000000000..f36f714a86f0348578896cad922c334c14a54ed5 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/warang_citi.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/wolofal.kmx b/developer/src/kmcmplib/tests/fixtures/wolofal.kmx new file mode 100644 index 0000000000000000000000000000000000000000..b3cc61d41341c86758dc1535b06b7c77109a783e Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/wolofal.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/xinaliq.kmx b/developer/src/kmcmplib/tests/fixtures/xinaliq.kmx new file mode 100644 index 0000000000000000000000000000000000000000..4eb748763bf078c80db3d2a5d4474a091ea8ca1c Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/xinaliq.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/yiddish_pasekh.kmx b/developer/src/kmcmplib/tests/fixtures/yiddish_pasekh.kmx new file mode 100644 index 0000000000000000000000000000000000000000..3836c816d5729a351009ea5ba0b52d945f536109 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/yiddish_pasekh.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/yidgha.kmx b/developer/src/kmcmplib/tests/fixtures/yidgha.kmx new file mode 100644 index 0000000000000000000000000000000000000000..7544013c02f4c8afe67e7f1cac04ebb08f875707 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/yidgha.kmx differ diff --git a/developer/src/kmcmplib/tests/fixtures/younger_futhark_short_twig.kmx b/developer/src/kmcmplib/tests/fixtures/younger_futhark_short_twig.kmx new file mode 100644 index 0000000000000000000000000000000000000000..81761ab9045c7dae54c3e03200f7a661b0609d81 Binary files /dev/null and b/developer/src/kmcmplib/tests/fixtures/younger_futhark_short_twig.kmx differ diff --git a/developer/src/kmcmplib/tests/get-test-source.sh b/developer/src/kmcmplib/tests/get-test-source.sh new file mode 100755 index 0000000000000000000000000000000000000000..13bea90e13219d0aaad84687a2794637df95c0d5 --- /dev/null +++ b/developer/src/kmcmplib/tests/get-test-source.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# +# Finds all keyboards in the keyboards repo (passed in $1) that are valid source +# keyboards (i.e. ///source/.kmn) +# +# Called from meson.build, so this script does not use build-utils.sh. Do not run this +# script directly. +# +set -eu +find "$1" -name '*.kmn' | grep -E '(release|experimental)/([a-z0-9_]+)/([a-z0-9_]+)/source/\3\.kmn$' diff --git a/developer/src/kmcmplib/tests/keyboards_commit_ref.txt b/developer/src/kmcmplib/tests/keyboards_commit_ref.txt new file mode 100644 index 0000000000000000000000000000000000000000..c8db9ade548b72bf9940548e68a41866ff18e50f --- /dev/null +++ b/developer/src/kmcmplib/tests/keyboards_commit_ref.txt @@ -0,0 +1 @@ +965ef1941f20a3bc0cb5d405792b4984cc46cd52 diff --git a/developer/src/kmcmplib/tests/kmcompxtest.cpp b/developer/src/kmcmplib/tests/kmcompxtest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ce542917d389df52ad136047d9b7ae09d15d9dd --- /dev/null +++ b/developer/src/kmcmplib/tests/kmcompxtest.cpp @@ -0,0 +1,233 @@ +/* + * Keyman is copyright (C) SIL International. MIT License. + * + * Tiny frame console app to compile a .kmx from a .kmn + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#else +#include +#endif + +using namespace std; + +vector < int > error_vec; + +#define CERR_FATAL 0x00008000 +#define CERR_ERROR 0x00004000 +#define CERR_WARNING 0x00002000 +#define CERR_HINT 0x00001000 + +int msgproc(int line, uint32_t dwMsgCode, char* szText, void* context) +{ + error_vec.push_back(dwMsgCode); + const char*t = "unknown"; + switch(dwMsgCode & 0xF000) { + case CERR_HINT: t=" hint"; break; + case CERR_WARNING: t="warning"; break; + case CERR_ERROR: t=" error"; break; + case CERR_FATAL: t=" fatal"; break; + } + printf("line %d %s %04.4x: %s\n", line, t, (unsigned int)dwMsgCode, szText); + return 1; +} + +#include "../src/filesystem.h" + +int main(int argc, char *argv[]) +{ + if(argc < 4) { + puts("Usage: kmcompxtest source.kmn output.kmx fixture.kmx"); + return __LINE__; + } + + char* kmn_file = argv[1]; + char* kmx_file = argv[2]; + char* reference_kmx = argv[3]; + + // Replace \ with / + for(char *p = kmn_file; *p; p++) { + if(*p == '\\') *p = '/'; + } + + for(char *p = kmx_file; *p; p++) { + if(*p == '\\') *p = '/'; + } + + for(char *p = reference_kmx; *p; p++) { + if(*p == '\\') *p = '/'; + } + + char first5[6] = "CERR_"; + char* pfirst5 = first5; + + KMCMP_COMPILER_OPTIONS kcopts; + kcopts.dwSize = sizeof(KMCMP_COMPILER_OPTIONS); + kcopts.ShouldAddCompilerVersion = false; // So we can compare against existing compiled keyboards that also don't have compiler version + if(!kmcmp_SetCompilerOptions(&kcopts)) { + return __LINE__; + } + + if(kmcmp_CompileKeyboardFile(kmn_file, kmx_file, true, false, true, msgproc, nullptr)) { + char* testname = strrchr( (char*) kmn_file, '/') + 1; + if(strncmp(testname, pfirst5, 5) == 0){ + return __LINE__; // exit code: CERR_ in Name + no Error found + } + + // On non-win32 platforms, we cannot get kmcmpdll.dll to build keyboards + // legacy-mode, so we'll compare to a hopefully existing file that we've + // been passed + FILE* fp1 = Open_File(kmx_file, "rb"); + if(!fp1) return __LINE__; + + + FILE* fp2 = Open_File(reference_kmx, "rb"); + if(!fp2) return __LINE__; // exit code: fail if no reference kmx file in build-folder + + fseek(fp1, 0, SEEK_END); + auto sz1 = ftell(fp1); + fseek(fp1, 0, SEEK_SET); + fseek(fp2, 0, SEEK_END); + auto sz2 = ftell(fp2); + fseek(fp2, 0, SEEK_SET); + if (sz1 != sz2) return __LINE__; // exit code: size of kmx-file in build differs from size of kmx-file in source folder + + char* buf1 = new char[sz1]; + char* buf2 = new char[sz1]; + fread(buf1, 1, sz1, fp1); + fread(buf2, 1, sz1, fp2); + return memcmp(buf1, buf2, sz1) ? __LINE__ : 0; // exit code: when contents of kmx-file in build differs from contents of kmx-file in source folder + // success: when contents of kmx-file in build and source folder are the same + } + else { /*if Errors found: check number (e.g. CERR_4061_balochi_phonetic.kmn should produce Error 4061)*/ + int error_val = 0; + char* testname = strrchr( (char*) kmn_file, '/') + 1; + + // Does testname contain CERR_ && contains '_' on pos 9 ? -> Get ErrorValue + if ((strncmp(testname, pfirst5, 5) == 0) && (testname[9] == '_')) { + char* ErrNr = strchr(testname, '_') +1 ; + std::istringstream(ErrNr) >> std::hex >> error_val; + + // check if error_val is in Array of Errors; if it is found return 0 (it's not an error) + for (int i = 0; i < error_vec.size() ; i++) { + if (error_vec[i] == error_val) { + return 0; // success: CERR_ in Name + Error (specified in CERR_Name) IS found + } + } + return __LINE__; // exit code: CERR_ in Name + Error (specified in CERR_Name) is NOT found + } + return __LINE__; // exit code: no correct CERR_ in Name + CompileKeyboardFile failed (i.e. test config is invalid) + } +} + + +bool equalIgnoreCase(const string& a, const string& b) +{ + return std::equal( + a.begin(), a.end(), + b.begin(), b.end(), + [](char a, char b) { + return tolower(a) == tolower(b); + } + ); +} + +// Returns TRUE if the keyboard has a &TARGETS store with +// 'any', 'windows', 'macosx', 'linux', or 'desktop' targets, +// or if no &TARGETS store exists (which is equivalent to +// 'windows'). +bool isDesktopKeyboard(FILE* fp) { + COMP_KEYBOARD fk; + + if(fseek(fp, 0, SEEK_SET) != 0) { + printf("isDesktopKeyboard: fseek(0) failed\n"); + exit(1); + } + + if(!fread(&fk, sizeof(fk), 1, fp)) { + printf("isDesktopKeyboard failed: could not read COMP_KEYBOARD\n"); + exit(1); + } + + // Note: this code assumes a valid .kmx. This is okay for a unit test + if(fseek(fp, fk.dpStoreArray, SEEK_SET) != 0) { + printf("isDesktopKeyboard failed: could not locate fk.dpStoreArray=%x\n", fk.dpStoreArray); + exit(1); + } + + PCOMP_STORE pfs = new COMP_STORE[fk.cxStoreArray]; + if(fread(pfs, sizeof(COMP_STORE), fk.cxStoreArray, fp) != fk.cxStoreArray) { + printf("isDesktopKeyboard failed: could not read fk.dpStoreArray=%x [%x]\n", fk.dpStoreArray, fk.cxStoreArray); + exit(1); + } + + PCOMP_STORE s = pfs; + + for(int i = 0; i < fk.cxStoreArray; i++, s++) { + if(s->dwSystemID != TSS_TARGETS) { + continue; + } + + // Read targets store + if(fseek(fp, s->dpString, SEEK_SET) != 0) { + printf("isDesktopKeyboard: could not seek to TSS_TARGETS.dpString %x\n", s->dpString); + exit(1); + } + + KMX_WCHAR buf[256]; + if(fread(buf, sizeof(KMX_WCHAR), 256, fp) == 0) { + printf("isDesktopKeyboard: could not read TSS_TARGETS.dpString %x\n", s->dpString); + exit(1); + } + buf[255] = 0; // sanity + + if(fseek(fp, 0, SEEK_SET) != 0) { + printf("isDesktopKeyboard: fseek(0) failed\n"); + exit(1); + } + + std::string targets1 = string_from_u16string(buf); + std::stringstream targets(targets1); + std::string target; + + printf("isDesktopKeyboard: TSS_TARGETS: %s\n", targets1.c_str()); + + delete[] pfs; + + while(targets >> target) { + //Matches KMXKeymanTargets from UKeymanTargets.pas + if(equalIgnoreCase(target, "any") || + equalIgnoreCase(target, "windows") || + equalIgnoreCase(target, "macosx") || + equalIgnoreCase(target, "linux") || + equalIgnoreCase(target, "desktop") + ) { + printf("isDesktopKeyboard: TSS_TARGETS does contain desktop target %s\n", target.c_str()); + return true; + } + } + + printf("isDesktopKeyboard: TSS_TARGETS does not contain desktop target\n"); + return false; + } + + delete[] pfs; + + if(fseek(fp, 0, SEEK_SET) != 0) { + printf("isDesktopKeyboard: fseek(0) failed\n"); + exit(1); + } + + printf("isDesktopKeyboard: TSS_TARGETS does not exist\n"); + return true; +} diff --git a/developer/src/kmcmplib/tests/meson.build b/developer/src/kmcmplib/tests/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..02f1a5e6126e57c8bfcb417b286bb0169f584c1b --- /dev/null +++ b/developer/src/kmcmplib/tests/meson.build @@ -0,0 +1,109 @@ +# +# Keyman is copyright (C) SIL International. MIT License. +# +# Cross platform build script to compile and run tests for kmcompx +# + +fs = import('fs') + +tests_flags = [] + +input_path = meson.current_source_dir() / '../../../../common/test/keyboards/baseline' +output_path = meson.current_build_dir() + +kmcompxtest = executable('kmcompxtest', 'kmcompxtest.cpp', + cpp_args: defns, + include_directories: inc, + name_suffix: name_suffix, + link_args: links + tests_flags, + objects: lib.extract_all_objects()) + +# Test keyboards that we have in Core + +tests = [ + 'k_000___null_keyboard', + 'k_001___basic_input_unicodei', + 'k_002___basic_input_unicode', + 'k_003___nul', + 'k_004___basic_input__shift_2_', + 'k_005___nul_with_initial_context', + 'k_006___vkey_input__shift_ctrl_', + 'k_007___vkey_input__ctrl_alt_', + 'k_008___vkey_input__ctrl_alt_2_', + 'k_012___ralt', + 'k_013___deadkeys', + 'k_014___groups_and_virtual_keys', + 'k_015___ralt_2', + 'k_017___space_mnemonic_kbd', + 'k_018___nul_testing', + 'k_019___multiple_deadkeys', + 'k_020___deadkeys_and_backspace', + 'k_021___options', + 'k_022___options_with_preset', + 'k_023___options_with_save', + 'k_024___options_with_save_and_preset', + 'k_025___options_with_reset', + 'k_026___system_stores', + 'k_027___system_stores_2', + 'k_028___smp', + 'k_029___beep', + 'k_030___multiple_groups', + 'k_031___caps_lock', + 'k_032___caps_control', + 'k_033___caps_always_off', + 'k_034___options_double_set_reset', + 'k_035___options_double_set_staged', + 'k_036___options___double_reset_staged', + 'k_037___options___double_reset', + 'k_038___punctkeys', + 'k_039___generic_ctrlalt', + 'k_040___long_context', + 'k_041___long_context_and_deadkeys', + 'k_042___long_context_and_split_deadkeys', + 'k_043___output_and_keystroke', + 'k_044___if_and_context', + 'k_045___deadkey_and_context', + 'k_046___deadkey_and_contextex', + 'k_047___caps_always_off_initially_on', + 'k_048___modifier_keys_keep_context' +] + +foreach kbd : tests + kbd_src = join_paths(input_path, kbd) + '.kmn' + kbd_obj = join_paths(output_path, kbd) + '.kmx' + test(kbd, kmcompxtest, args: [kbd_src, kbd_obj, join_paths(input_path, kbd) + '.kmx']) +endforeach + +# Test fixtures that come from keyboards repo + +keyboards_root = meson.current_source_dir() / 'keyboards' + +if build_machine.system() == 'windows' + test_source = run_command('run-shell.bat', 'get-test-source.sh', keyboards_root, capture: true, check: true) +else + test_source = run_command('get-test-source.sh', keyboards_root, capture: true, check: true) +endif + +tests = test_source.stdout().strip().split('\n') + +foreach kbd : tests + test_basename = fs.replace_suffix(fs.name(kbd), '') + + # kbd is going to be an absolute path + kbd_obj = output_path / test_basename + '.kmx' + reference_kmx = meson.current_source_dir() / 'fixtures' / test_basename + '.kmx' + + if fs.is_file(reference_kmx) + test(test_basename, kmcompxtest, args: [kbd, kbd_obj, reference_kmx]) + endif +endforeach + + +apitest = executable('api-test', 'api-test.cpp', + cpp_args: defns, + include_directories: inc, + name_suffix: name_suffix, + link_args: links + tests_flags, + objects: lib.extract_all_objects()) + +test('api-test', apitest) \ No newline at end of file diff --git a/developer/src/kmcmplib/tests/prep.sh b/developer/src/kmcmplib/tests/prep.sh new file mode 100755 index 0000000000000000000000000000000000000000..058d4a1b9b0bfdd50fe13d29bcbdff7af508bd3c --- /dev/null +++ b/developer/src/kmcmplib/tests/prep.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# +# Generates fixtures for testing against the legacy compiler +# +# Assumes that the +# + +# Exit on command failure and when using unset variables: +set -eu + +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../../resources/build/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +cd "$THIS_SCRIPT_PATH" + +builder_describe \ +"Generates fixtures for testing against the legacy compiler. + + Developer must be built locally and binaries should be in developer/bin/. + + Assumes that the keyboards repository exists and is clean. Will record the + commit hash to allow corresponding CI builds to use the same commit hash + for validation." \ + clean \ + build \ + "--keyboards-root,-k=KEYBOARDS_ROOT Path to keyboards repository" + +builder_parse "$@" + +if ! builder_has_option --keyboards-root; then + builder_die "--keyboards-root option is required" +fi + +if [[ ! -d "$KEYBOARDS_ROOT/.git" ]] || [[ ! -f "$KEYBOARDS_ROOT/tools/regression.sh" ]]; then + builder_die "Path $KEYBOARDS_ROOT does not appear to be a valid keyboard repository" +fi + +if builder_start_action clean; then + rm -rf "$THIS_SCRIPT_PATH/fixtures" + rm -f "$THIS_SCRIPT_PATH/keyboards_commit_ref.txt" + builder_finish_action success clean +fi + +if builder_start_action build; then + # yes, remove existing fixtures before build so we don't end up with stale fixtures + rm -rf "$THIS_SCRIPT_PATH/fixtures" + + # record the revision of the keyboards repo + pushd "$KEYBOARDS_ROOT" > /dev/null + git rev-parse head > "$THIS_SCRIPT_PATH/keyboards_commit_ref.txt" + popd > /dev/null + + "$KEYBOARDS_ROOT/tools/regression.sh" --use-legacy-compiler --local "$KEYMAN_ROOT/developer/bin/" --output "$THIS_SCRIPT_PATH/fixtures/" + + cd "$THIS_SCRIPT_PATH" + + # We don't need visual keyboards + rm ./fixtures/*.kvk + # Nor do we need kmw outputs + rm ./fixtures/*.js + # Finally, we remove any keyboards over 500kb, as we won't automatically test them for now + # TODO: consider if we want to keep those large keyboards in the future + find ./fixtures/ -size +500k -exec rm {} \+ + builder_finish_action success build +fi \ No newline at end of file diff --git a/developer/src/kmcmplib/tests/run-shell.bat b/developer/src/kmcmplib/tests/run-shell.bat new file mode 100644 index 0000000000000000000000000000000000000000..f0a51d786900e77246a032380d8813cab0fd25cc --- /dev/null +++ b/developer/src/kmcmplib/tests/run-shell.bat @@ -0,0 +1,7 @@ +@echo off +if defined GIT_BASH_FOR_KEYMAN ( + set GIT_BASH=%GIT_BASH_FOR_KEYMAN% +) else ( + set GIT_BASH="%ProgramFiles%\git\bin\bash.exe" --init-file "%ProgramFiles%\Git\etc\profile" -l +) +%GIT_BASH% %1 %2 %3 %4 %5 %6 %7 %8 %9 \ No newline at end of file diff --git a/developer/src/kmcmplib/version.rc b/developer/src/kmcmplib/version.rc new file mode 100644 index 0000000000000000000000000000000000000000..b963c10ddb1be06b12eec81667301c4f551c3cc5 --- /dev/null +++ b/developer/src/kmcmplib/version.rc @@ -0,0 +1,32 @@ +#include "../../../common/windows/cpp/include/keymanversion.h" + +1 VERSIONINFO + FILEVERSION KV_FILEVERSION + PRODUCTVERSION KV_PRODUCTVERSION + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0C0904E4" + BEGIN + VALUE "CompanyName", KV_COMPANY_NAME + VALUE "FileDescription", "Keyman compiler library\0" + VALUE "FileVersion", KV_VERSION_STRING + VALUE "InternalName", "KMCOMP\0" + VALUE "LegalCopyright", KV_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", KV_LEGAL_TRADEMARKS + VALUE "OriginalFilename", "KMCOMP.DLL\0" + VALUE "ProductName", "Keyman Developer\0" + VALUE "ProductVersion", KV_VERSION_STRING + VALUE "Comments", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0xc09, 1252 + END + END diff --git a/developer/src/kmcmplib/wasm.build.linux.in b/developer/src/kmcmplib/wasm.build.linux.in new file mode 100644 index 0000000000000000000000000000000000000000..c5e61a9bda94e66bcc6c147361c56c4488ef60c6 --- /dev/null +++ b/developer/src/kmcmplib/wasm.build.linux.in @@ -0,0 +1,4 @@ +[binaries] +c = ['$EMSCRIPTEN_BASE/emcc.py'] +cpp = ['$EMSCRIPTEN_BASE/em++.py'] +ar = ['$EMSCRIPTEN_BASE/emar.py'] diff --git a/developer/src/kmcmplib/wasm.build.mac.in b/developer/src/kmcmplib/wasm.build.mac.in new file mode 100644 index 0000000000000000000000000000000000000000..c5e61a9bda94e66bcc6c147361c56c4488ef60c6 --- /dev/null +++ b/developer/src/kmcmplib/wasm.build.mac.in @@ -0,0 +1,4 @@ +[binaries] +c = ['$EMSCRIPTEN_BASE/emcc.py'] +cpp = ['$EMSCRIPTEN_BASE/em++.py'] +ar = ['$EMSCRIPTEN_BASE/emar.py'] diff --git a/developer/src/kmcmplib/wasm.build.win.in b/developer/src/kmcmplib/wasm.build.win.in new file mode 100644 index 0000000000000000000000000000000000000000..68c21fb00f5f6ba0a3e0316aabbf894500bd0f3d --- /dev/null +++ b/developer/src/kmcmplib/wasm.build.win.in @@ -0,0 +1,4 @@ +[binaries] +c = ['python.exe', '$EMSCRIPTEN_BASE/emcc.py'] +cpp = ['python.exe', '$EMSCRIPTEN_BASE/em++.py'] +ar = ['python.exe', '$EMSCRIPTEN_BASE/emar.py'] diff --git a/developer/src/kmcmplib/wasm.defs.build b/developer/src/kmcmplib/wasm.defs.build new file mode 100644 index 0000000000000000000000000000000000000000..4a598a1e1c121d759e5637df28d17dabcb675734 --- /dev/null +++ b/developer/src/kmcmplib/wasm.defs.build @@ -0,0 +1,18 @@ +[binaries] +c = ['emcc.py'] +cpp = ['em++.py'] +ar = ['emar.py'] +exe_wrapper = 'node' + +[properties] +root = '$EMSCRIPTEN_BASE/system' +shared_lib_suffix = 'js' +static_lib_suffix = 'js' +shared_module_suffix = 'js' +exe_suffix = 'js' + +[host_machine] +system = 'emscripten' +cpu_family = 'x86' +cpu = 'i686' +endian = 'little' diff --git a/developer/src/kmcomp/main.pas b/developer/src/kmcomp/main.pas index 4aa29cf6c1ace54494285d0f9bd9c1f701d45040..5a29927a807bccd47dea671dbb6ce8d629a1f727 100644 --- a/developer/src/kmcomp/main.pas +++ b/developer/src/kmcomp/main.pas @@ -65,7 +65,7 @@ uses UKeymanTargets; function CompileKeyboard(FInFile, FOutFile: string; FDebug, FWarnAsError: Boolean): Boolean; forward; // I4706 -function KCSetCompilerOptions(const FInFile: string; FShouldAddCompilerVersion: Boolean): Boolean; forward; +function KCSetCompilerOptions(const FInFile: string; FShouldAddCompilerVersion, FUseKmcmpLib: Boolean): Boolean; forward; //function CompilerMessage(line: Integer; msgcode: LongWord; text: PAnsiChar): Integer; stdcall; forward; procedure FixupPathSlashes(var path: string); forward; @@ -90,6 +90,7 @@ var FParamDistribution: Boolean; FMergingValidateIds: Boolean; FShouldAddCompilerVersion: Boolean; + FUseKmcmpLib: Boolean; FJsonSchemaPath: string; FParamSourcePath: string; FParamHelpLink: string; @@ -116,6 +117,7 @@ begin FColorMode := cmDefault; FShouldAddCompilerVersion := True; + FUseKmcmpLib := True; FParamInfile := ''; FParamOutfile := ''; @@ -191,6 +193,8 @@ begin FColorMode := cmForceNoColor else if s = '-no-compiler-version' then FShouldAddCompilerVersion := False + else if s = '-use-legacy-compiler' then + FUseKmcmpLib := False else if (s = '-help') or (s = '-h') then begin // Force help @@ -219,6 +223,8 @@ begin writeln(SKeymanDeveloperName + ' Compiler (32-bit)'); {$ENDIF} writeln('Version ' + CKeymanVersionInfo.VersionWithTag + ', ' + GetVersionCopyright); + if not FUseKmcmpLib then + writeln('Note: using legacy compiler'); end; if FError or (FParamInfile = '') then @@ -228,7 +234,7 @@ begin writeln(''); writeln('Usage: '+cmd+' [-s[s]] [-nologo] [-c] [-d] [-w] [-cfc] [-v[s|d]] [-source-path path] [-schema-path path] '); writeln(' '+spc+' [-m] infile [-m infile] [-t target] [outfile.kmx|outfile.js [error.log]]'); // I4699 - writeln(' '+spc+' [-add-help-link path] [-color|-no-color] [-no-compiler-version]'); + writeln(' '+spc+' [-add-help-link path] [-color|-no-color] [-no-compiler-version] [-use-legacy-compiler]'); writeln(' '+spc+' [-extract-keyboard-info field[,field...]]'); writeln(' infile can be a .kmn file (Keyboard Source, .kps file (Package Source), or .kpj (project)'); // I4699 // I4825 writeln(' if -v specified, can also be a .keyboard_info file'); @@ -252,6 +258,7 @@ begin writeln(' uses console mode to determine whether color should be used.'); writeln; writeln(' -no-compiler-version Don''t embed the compiler version stores, useful for regression tests.'); + writeln(' -use-legacy-compiler Use legacy compiler (will be removed in 18.0)'); writeln; writeln(' JSON .keyboard_info compile targets:'); writeln(' -v[s] validate infile against source schema'); @@ -291,7 +298,7 @@ begin TProjectLogConsole.Create(FSilent, FFullySilent, hOutfile, FColorMode); - KCSetCompilerOptions(FParamInfile, FShouldAddCompilerVersion); + KCSetCompilerOptions(FParamInfile, FShouldAddCompilerVersion, FUseKmcmpLib); if FValidateRepoChanges then FError := not TValidateRepoChanges.Execute(FParamInfile, FParamOutfile) @@ -317,7 +324,7 @@ begin ExitCode := 1; end; -function KCSetCompilerOptions(const FInFile: string; FShouldAddCompilerVersion: Boolean): Boolean; +function KCSetCompilerOptions(const FInFile: string; FShouldAddCompilerVersion, FUseKmcmpLib: Boolean): Boolean; var opt: TCompilerOptions; begin @@ -325,6 +332,7 @@ begin opt.dwSize := sizeof(TCompilerOptions); opt.ShouldAddCompilerVersion := FShouldAddCompilerVersion; + opt.UseKmcmpLib := FUseKmcmpLib; Result := SetCompilerOptions(@opt, @CompilerMessageW); diff --git a/developer/src/test/auto/kmcomp/test.bat b/developer/src/test/auto/kmcomp/test.bat index 0fbaefa7f26fd8827be74e1491069e8f8e3da745..808c2f9068b3260fa6f2fcd30386d6072c5fccfb 100644 --- a/developer/src/test/auto/kmcomp/test.bat +++ b/developer/src/test/auto/kmcomp/test.bat @@ -143,26 +143,38 @@ echo %BLUE%TEST: %1 %WHITE% if exist error.log del error.log "%compiler%" -no-color -nologo -ss -w tests.kpj -t "%2" > error.log if !ERRORLEVEL! GTR 0 ( + echo %RED%FAILED: expected %2 to be a valid keyboard.%WHITE% 1>&2 + echo --------------------------------------------------------------------------- + echo %BLUE%## error.log%WHITE% type error.log + echo --------------------------------------------------------------------------- del error.log - echo %RED%FAILED: expected %2 to be a valid keyboard.%WHITE% 1>&2 exit /b 1 ) if "!outfile!" == "" ( findstr /L /C:%3 error.log > nul if !ERRORLEVEL! GTR 0 ( + echo %RED%FAILED: expected compile results to contain message %3.%WHITE% 1>&2 + echo --------------------------------------------------------------------------- + echo %BLUE%## error.log%WHITE% type error.log + echo --------------------------------------------------------------------------- del error.log - echo %RED%FAILED: expected compile results to contain message %3.%WHITE% 1>&2 exit /b 1 ) ) else ( fc error.log !outfile! > nul if !ERRORLEVEL! GTR 0 ( + echo %RED%FAILED: expected output in error.log did not match !outfile!.%WHITE% 1>&2 + echo --------------------------------------------------------------------------- + echo %BLUE%## error.log%WHITE% type error.log + echo --------------------------------------------------------------------------- + echo %BLUE%## !outfile!%WHITE% + type !outfile! + echo --------------------------------------------------------------------------- del error.log - echo %RED%FAILED: expected output in error.log did not match !outfile!.%WHITE% 1>&2 exit /b 1 ) ) diff --git a/developer/src/test/auto/kmcomp/test_194_Filename_case.kvk b/developer/src/test/auto/kmcomp/test_194_Filename_case.kvk index 2d494cfc2e61ff74440731f29a77ea42c37b2d6d..a46a1fffae959d0c39646bdc37b3c9a105f5911e 100644 Binary files a/developer/src/test/auto/kmcomp/test_194_Filename_case.kvk and b/developer/src/test/auto/kmcomp/test_194_Filename_case.kvk differ diff --git a/developer/src/tike/dialogs/UfrmOptions.dfm b/developer/src/tike/dialogs/UfrmOptions.dfm index 5968496f38e62dbc14b66ee29bca4aa751dadde7..d20db381fd77cb69b121c18ec52477107ede8a16 100644 --- a/developer/src/tike/dialogs/UfrmOptions.dfm +++ b/developer/src/tike/dialogs/UfrmOptions.dfm @@ -30,7 +30,7 @@ inherited frmOptions: TfrmOptions Width = 125 Height = 25 Caption = '&Proxy Settings...' - TabOrder = 4 + TabOrder = 5 OnClick = cmdProxySettingsClick end object gbExternalEditor: TGroupBox @@ -39,7 +39,7 @@ inherited frmOptions: TfrmOptions Width = 401 Height = 45 Caption = '&External Editor Path' - TabOrder = 1 + TabOrder = 2 object editExternalEditorPath: TEdit Left = 8 Top = 16 @@ -62,7 +62,7 @@ inherited frmOptions: TfrmOptions Width = 125 Height = 25 Caption = 'S&MTP Settings...' - TabOrder = 3 + TabOrder = 6 OnClick = cmdSMTPSettingsClick end object chkOpenKeyboardFilesInSourceView: TCheckBox @@ -71,7 +71,7 @@ inherited frmOptions: TfrmOptions Width = 221 Height = 17 Caption = 'Open &keyboard files in source view' - TabOrder = 0 + TabOrder = 1 end object cmdResetToolWindows: TButton Left = 8 @@ -79,7 +79,7 @@ inherited frmOptions: TfrmOptions Width = 125 Height = 25 Caption = '&Reset tool windows' - TabOrder = 2 + TabOrder = 4 OnClick = cmdResetToolWindowsClick end object chkAllowMultipleInstances: TCheckBox @@ -88,7 +88,7 @@ inherited frmOptions: TfrmOptions Width = 289 Height = 17 Caption = '&Allow multiple instances of Keyman Developer' - TabOrder = 5 + TabOrder = 0 end object gbDefaultProjectPath: TGroupBox Left = 8 @@ -96,7 +96,7 @@ inherited frmOptions: TfrmOptions Width = 401 Height = 45 Caption = '&Default Project Folder' - TabOrder = 6 + TabOrder = 3 object editDefaultProjectPath: TEdit Left = 8 Top = 16 @@ -136,14 +136,14 @@ inherited frmOptions: TfrmOptions Width = 401 Height = 73 Caption = 'Privacy' - TabOrder = 9 + TabOrder = 10 object chkReportUsage: TCheckBox Left = 8 Top = 44 Width = 311 Height = 17 Caption = '&Share anonymous usage statistics with keyman.com' - TabOrder = 0 + TabOrder = 1 end object chkReportErrors: TCheckBox Left = 8 @@ -151,9 +151,17 @@ inherited frmOptions: TfrmOptions Width = 311 Height = 17 Caption = 'Automatically report &errors to keyman.com' - TabOrder = 1 + TabOrder = 0 end end + object chkUseLegacyCompiler: TCheckBox + Left = 152 + Top = 244 + Width = 250 + Height = 17 + Caption = 'Use legacy .kmn compiler (removing in 18.0)' + TabOrder = 9 + end end object tabEditor: TTabSheet Caption = 'Editor' diff --git a/developer/src/tike/dialogs/UfrmOptions.pas b/developer/src/tike/dialogs/UfrmOptions.pas index 77aa090ea2f6f27e18cea8bd201322965132158d..3976e6ceb572971856d5b400c09fcc648ac73226 100644 --- a/developer/src/tike/dialogs/UfrmOptions.pas +++ b/developer/src/tike/dialogs/UfrmOptions.pas @@ -105,6 +105,7 @@ type gbServer: TGroupBox; chkListLocalURLs: TCheckBox; cmdConfigureServer: TButton; + chkUseLegacyCompiler: TCheckBox; procedure FormCreate(Sender: TObject); procedure cmdOKClick(Sender: TObject); procedure cmdDefaultFontClick(Sender: TObject); @@ -194,6 +195,8 @@ begin chkAutoSaveBeforeCompiling.Checked := AutoSaveBeforeCompiling; chkOSKAutoSaveBeforeImporting.Checked := OSKAutoSaveBeforeImporting; + chkUseLegacyCompiler.Checked := UseLegacyCompiler; + chkCharMapAutoLookup.Checked := CharMapAutoLookup; chkCharMapDisableDatabaseLookups.Checked := CharMapDisableDatabaseLookups; @@ -295,6 +298,8 @@ begin AutoSaveBeforeCompiling := chkAutoSaveBeforeCompiling.Checked; OSKAutoSaveBeforeImporting := chkOSKAutoSaveBeforeImporting.Checked; + UseLegacyCompiler := chkUseLegacyCompiler.Checked; + ServerUseLocalAddresses := chkListLocalURLs.Checked; CharMapAutoLookup := chkCharMapAutoLookup.Checked; diff --git a/developer/src/tike/main/KeymanDeveloperOptions.pas b/developer/src/tike/main/KeymanDeveloperOptions.pas index 677f55d5909c800a59b1c7db06b16c3e203fb6ca..d7068788cd9611fbe475718ba6d52c846a0d58f4 100644 --- a/developer/src/tike/main/KeymanDeveloperOptions.pas +++ b/developer/src/tike/main/KeymanDeveloperOptions.pas @@ -70,6 +70,7 @@ type FServerNgrokToken: string; FServerNgrokRegion: string; FServerKeepAlive: Boolean; + FUseLegacyCompiler: Boolean; procedure CloseRegistry; procedure OpenRegistry; function regReadString(const nm, def: string): string; @@ -104,6 +105,8 @@ type property AutoSaveBeforeCompiling: Boolean read FAutoSaveBeforeCompiling write FAutoSaveBeforeCompiling; property OSKAutoSaveBeforeImporting: Boolean read FOSKAutoSaveBeforeImporting write FOSKAutoSaveBeforeImporting; + property UseLegacyCompiler: Boolean read FUseLegacyCompiler write FUseLegacyCompiler; + property ReportErrors: Boolean read FReportErrors write FReportErrors; property ReportUsage: Boolean read FReportUsage write FReportUsage; @@ -215,6 +218,8 @@ begin FAutoSaveBeforeCompiling := regReadBool(SRegValue_IDEOptAutoSaveBeforeCompiling, False); FOSKAutoSaveBeforeImporting := regReadBool(SRegValue_IDEOptOSKAutoSaveBeforeImporting, False); + FUseLegacyCompiler := regReadBool(SRegValue_IDEOptUseLegacyCompiler, False); + FServerDefaultPort := regReadInt(SRegValue_IDEOptServerPort, 8008); FServerKeepAlive := regReadBool(SRegValue_IDEOptServerKeepAlive, False); FServerUseLocalAddresses := regReadBool(SRegValue_IDEOptServerUseLocalAddresses, True); @@ -276,6 +281,7 @@ begin regWriteBool(SRegValue_IDEOptAutoSaveBeforeCompiling, FAutoSaveBeforeCompiling); regWriteBool(SRegValue_IDEOptOSKAutoSaveBeforeImporting, FOSKAutoSaveBeforeImporting); + regWriteBool(SRegValue_IDEOptUseLegacyCompiler, FUseLegacyCompiler); regWriteInt(SRegValue_IDEOptServerPort, FServerDefaultPort); regWriteBool(SRegValue_IDEOptServerKeepAlive, FServerKeepAlive); diff --git a/developer/src/tike/project/Keyman.Developer.System.Project.kmnProjectFileAction.pas b/developer/src/tike/project/Keyman.Developer.System.Project.kmnProjectFileAction.pas index 4f0503509c0c83fbf0df1a56495288a003a2fc14..703a1e4a0b6edd891950b647e5240c2e1250f02b 100644 --- a/developer/src/tike/project/Keyman.Developer.System.Project.kmnProjectFileAction.pas +++ b/developer/src/tike/project/Keyman.Developer.System.Project.kmnProjectFileAction.pas @@ -19,6 +19,8 @@ type public function CompileKeyboard: Boolean; function Clean: Boolean; + function DoSetCompilerOptions(addVersion, + useLegacyCompiler: Boolean): Boolean; end; implementation @@ -106,6 +108,22 @@ begin end; end; +function TkmnProjectFileAction.DoSetCompilerOptions(addVersion: Boolean; useLegacyCompiler: Boolean): Boolean; +var + options: COMPILER_OPTIONS; +begin + TProject.CompilerMessageFile := Self; + options.dwSize := sizeof(COMPILER_OPTIONS); + options.ShouldAddCompilerVersion := addVersion; + options.UseKmcmpLib := not useLegacyCompiler; + if not SetCompilerOptions(@options, ProjectCompilerMessage) then + begin + Log(plsFatal, 'Unable to set compiler options', CERR_FATAL, 0); + Exit(False); + end; + Result := True; +end; + function TkmnProjectFileAction.CompileKeyboard: Boolean; var KMXFileName: String; diff --git a/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas b/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas index 9b2dd467c5be2011eaa205c91612b12c9fb9ec99..72c9b43fd47f817361314b093eaef8dbee180750 100644 --- a/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas +++ b/developer/src/tike/project/Keyman.Developer.UI.Project.kmnProjectFileUI.pas @@ -130,7 +130,11 @@ begin if not FSilent then frmMessages.DoShowForm; - Result := ProjectFile.CompileKeyboard; + Result := + // Note: we do not surface the ability to exclude version information from + // the TIKE compiler; this must be done from kmcomp.exe. + ProjectFile.DoSetCompilerOptions(True, FKeymanDeveloperOptions.UseLegacyCompiler) and + ProjectFile.CompileKeyboard; if Result and TServerDebugAPI.Running and diff --git a/docs/build/windows.md b/docs/build/windows.md index ef190dd96e8a80084c302f6a9e0f657d0c4fa77f..ed2ca7fb8b978e186258a7113a2294834f40a8c9 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -101,12 +101,13 @@ Building: * Ant * Gradle * Maven +* OpenJDK 11 ```ps1 # Elevated PowerShell choco install android-sdk android-studio ant gradle maven # optionally install sdk images -sdkmanager "system-images;android-30;google_apis;armeabi-v7a" +sdkmanager "system-images;android-33;google_apis;armeabi-v7a" sdkmanager --update sdkmanager --licenses ``` @@ -114,6 +115,12 @@ sdkmanager --licenses * Run Android Studio once after installation to install additional components such as emulator images and SDK updates. +**Required environment variables**: +* [`JAVA_HOME`](#java_home) + +**Optional environment variables**: +* [`JAVA_HOME_11`](#java_home) + Building: * [Building Keyman for Android](../../android/README.md) @@ -175,9 +182,9 @@ You can use Windows Settings to add these environment variables permanently: * KeymanWeb **Requirements**: -* emscripten 2.0.23+ +* emscripten 3.1.32 * node.js 18+ -* openjdk 8+ +* [openjdk 11](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-11)+ ```ps1 # Elevated PowerShell @@ -341,6 +348,17 @@ To include UserDefines.mak in the build, use the command line parameter `-DUSERDEFINES`. You can also set an environment variable `USERDEFINES=1` to get the same result. +### JAVA_HOME + +This environment variable tells Gradle what version of Java to use for building Keyman for Android. + +**Multiple versions of Java:** If you need to build Keyman for Android 16.0 or older versions, you can set `JAVA_HOME_11` to the OpenJDK 11 path and `JAVA_HOME` to the OpenJDK 8 path. This will build both versions correctly from command line. But note that you do need to update your `JAVA_HOME` env var to the associated version before opening Android Studio and loading any Android projects. `JAVA_HOME_11` is mostly used by CI. + +```bat +SET JAVA_HOME="path to OpenJDK 8" +SET JAVA_HOME_11="path to OpenJDK 11" +``` + ## Optional Tools * sentry-cli (optional) diff --git a/docs/settings/linux/launch.json b/docs/settings/linux/launch.json index a66c76f0a9b749dff3b6c97f1d32b8071f176b65..bfae335300d1980249d74352ff9ce193ede01ca9 100644 --- a/docs/settings/linux/launch.json +++ b/docs/settings/linux/launch.json @@ -20,7 +20,7 @@ "name": "Launch kmx unit tests", "target": "build/arch/debug/tests/unit/kmx/kmx", "cwd": "${workspaceRoot}/core/", - "arguments": "tests/unit/kmx/033\\ -\\ caps\\ always\\ off.km{n,x}", + "arguments": "tests/unit/kmx/k_033___caps_always_off.km{n,x}", "valuesFormatting": "parseText" }, { diff --git a/ios/samples/build_common.sh b/ios/samples/build_common.sh index c3397e29b4006efea8280bdecd500962c8df1176..e1ed7ee95fb07307caf721d4c718084df9e333bf 100755 --- a/ios/samples/build_common.sh +++ b/ios/samples/build_common.sh @@ -129,7 +129,7 @@ if [ $DO_UPDATE = true ]; then fi # Copy resources. - cp -Rf "$KEYMAN_ENGINE_FRAMEWORK_SRC" "$KEYMAN_ENGINE_FRAMEWORK_DST" + /bin/cp -Rf "$KEYMAN_ENGINE_FRAMEWORK_SRC" "$KEYMAN_ENGINE_FRAMEWORK_DST" fi if [ $CODE_SIGN = true ]; then diff --git a/linux/ibus-keyman/tests/README.md b/linux/ibus-keyman/tests/README.md index f7537a79fda820adb7b340a52c063e5362d2efe1..046333be9d4a8218b62632f380579eb51acfd43e 100644 --- a/linux/ibus-keyman/tests/README.md +++ b/linux/ibus-keyman/tests/README.md @@ -1,6 +1,6 @@ # ibus-keyman integration tests -The ibus-keyman integration tests run the tests defined in `core/tests/unit/kmx`. +The ibus-keyman integration tests run the tests defined in `common/test/keyboards/baseline`. The tests run in a separate Xephyr session. Any dconf settings that have to be set during the tests are stored in `~/.config/glib-2.0/settings/keyfile`. @@ -19,7 +19,7 @@ scripts/run-tests.sh ### Run specific tests To run a single test you pass the testname (as found in -`core/build/arch/*/tests/unit/kmx`). Multiple tests should be separated by space. +`common/test/keyboards/baseline`). Multiple tests should be separated by space. ```bash scripts/run-tests.sh -- k_000___null_keyboard k_005___nul_with_initial_context diff --git a/linux/ibus-keyman/tests/scripts/run-tests.sh b/linux/ibus-keyman/tests/scripts/run-tests.sh index dc6850758c71b6e44f9f86f11003149ebffe7a3e..81f32bd4efc2b62e2b84f040ffbeac7a60949d85 100755 --- a/linux/ibus-keyman/tests/scripts/run-tests.sh +++ b/linux/ibus-keyman/tests/scripts/run-tests.sh @@ -72,7 +72,7 @@ function run_tests() { # TODO: we are borrowing the KMX tests out of core; these should be shared in common # to avoid deep links like this in future - KMX_TEST_DIR="${TOP_SRCDIR}"/../../core/tests/unit/kmx + KMX_TEST_DIR="${TOP_SRCDIR}"/../../common/test/keyboards/baseline if [ ! -d "$TESTDIR" ] || ! [[ $(find "${TESTDIR}/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then if [[ $(find "${KMX_TEST_DIR}/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then diff --git a/linux/ibus-keyman/tests/scripts/setup-tests.sh b/linux/ibus-keyman/tests/scripts/setup-tests.sh index e3750f7430280f9ab0e9df5b110b2bcc04b47f0f..94400d40f2602b5b768c673007ffcebbde796972 100755 --- a/linux/ibus-keyman/tests/scripts/setup-tests.sh +++ b/linux/ibus-keyman/tests/scripts/setup-tests.sh @@ -34,7 +34,7 @@ fi # TODO: we are borrowing the KMX tests out of core; these should be shared in common # to avoid deep links like this in future -KMX_TEST_DIR="${TOP_SRCDIR}"/../../core/tests/unit/kmx +KMX_TEST_DIR="${TOP_SRCDIR}"/../../common/test/keyboards/baseline if [ ! -d "$TESTDIR" ] || ! [[ $(find "${TESTDIR}/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then if [[ $(find "${KMX_TEST_DIR}/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then diff --git a/linux/scripts/dist.sh b/linux/scripts/dist.sh index 87003f0def416d2210223ce2b6c3c419116b15a8..7b1be441d90374e87053c328b4d973c043bbe82a 100755 --- a/linux/scripts/dist.sh +++ b/linux/scripts/dist.sh @@ -33,9 +33,17 @@ dch keyman --newversion "${VERSION}" --force-bad-version --nomultimaint dpkg-source --tar-ignore=*~ --tar-ignore=.git --tar-ignore=.gitattributes \ --tar-ignore=.gitignore --tar-ignore=experiments --tar-ignore=debian \ --tar-ignore=.github --tar-ignore=.vscode --tar-ignore=android \ - --tar-ignore=common/models --tar-ignore=common/predictive-text \ - --tar-ignore=common/resources --tar-ignore=common/schemas \ - --tar-ignore=common/test --tar-ignore=common/web --tar-ignore=common/windows \ + \ + --tar-ignore=common/models \ + --tar-ignore=common/predictive-text \ + --tar-ignore=common/resources \ + --tar-ignore=common/schemas \ + --tar-ignore=common/test/keyboards/build.* \ + --tar-ignore=common/test/predictive-text \ + --tar-ignore=common/test/resources \ + --tar-ignore=common/web \ + --tar-ignore=common/windows \ + \ --tar-ignore=core/build \ --tar-ignore=developer --tar-ignore=docs --tar-ignore=ios \ --tar-ignore=linux/keyman-config/buildtools/build-langtags.py --tar-ignore=__pycache__ \ diff --git a/mac/Keyman4MacIM/localdeploy.sh b/mac/Keyman4MacIM/localdeploy.sh index 6b56f7fc3e57ad80077b8de7168798d8d6969f3d..b09bf36bf6949c95a8c3614e720604f6a73d4719 100755 --- a/mac/Keyman4MacIM/localdeploy.sh +++ b/mac/Keyman4MacIM/localdeploy.sh @@ -42,7 +42,7 @@ if [[ -d "$KM4MIM_INSTALL_PATH" ]]; then rm -Rf "$KM4MIM_INSTALL_PATH" fi echo "Copying $KM4MIM_APP_PATH to $IMLIBRARY_PATH..." -cp -R "$KM4MIM_APP_PATH" "$IMLIBRARY_PATH" +/bin/cp -R "$KM4MIM_APP_PATH" "$IMLIBRARY_PATH" if [[ -d "$KM4MIM_INSTALL_PATH" ]]; then exit 0 diff --git a/mac/Keyman4MacIM/make-km-dmg.sh b/mac/Keyman4MacIM/make-km-dmg.sh index 645abb72edbf1e1e463a6bb3470889a4106395be..b79f40e8b4842ad861c493383e892a5fc8270cb6 100755 --- a/mac/Keyman4MacIM/make-km-dmg.sh +++ b/mac/Keyman4MacIM/make-km-dmg.sh @@ -174,7 +174,7 @@ displayInfo "Copying files from \"$SOURCE_KM_APP\"..." find "$DEST_KM_APP" -mindepth 1 -maxdepth 1 echo "---------" find "$DEST_KM_APP" -mindepth 1 -maxdepth 1 -print0 | xargs -0 rm -rf -cp -fR "$SOURCE_KM_APP/" "$DEST_KM_APP" +/bin/cp -fR "$SOURCE_KM_APP/" "$DEST_KM_APP" echo "---- Listing info in /Volumes/Keyman/ ----" echo "DEST_KM_APP=$DEST_KM_APP" diff --git a/mac/setup/build.sh b/mac/setup/build.sh index 11fbb66df808f0c825407828bfac17d67c912358..40860222daf7d884a4b6f2ced65160d6059e6c7f 100755 --- a/mac/setup/build.sh +++ b/mac/setup/build.sh @@ -62,10 +62,10 @@ mkdir -p "$TARGETPATH" rm -rf "$TARGETAPP" || true # Copy new install image to output folder -cp -R "$SOURCEAPP" "$TARGETPATH/" +/bin/cp -R "$SOURCEAPP" "$TARGETPATH/" # Copy Keyman.app into install image -cp -R "$KEYMANAPP" "$TARGETAPP/Contents/MacOS/Keyman.app" +/bin/cp -R "$KEYMANAPP" "$TARGETAPP/Contents/MacOS/Keyman.app" # Copy textinputsource into install image cp textinputsource/textinputsource "$TARGETAPP/Contents/MacOS/textinputsource" diff --git a/oem/firstvoices/android/app/build.gradle b/oem/firstvoices/android/app/build.gradle index 737d3462c3071e5fb16a498d5efafc2dee2e4a6d..6259b7bb8c41f7913b99a8370f139db3e5e93c00 100644 --- a/oem/firstvoices/android/app/build.gradle +++ b/oem/firstvoices/android/app/build.gradle @@ -10,11 +10,6 @@ apply from: "$rootPath/version.gradle" android { compileSdkVersion 33 - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - defaultConfig { applicationId "com.firstvoices.keyboards" minSdkVersion 21 @@ -70,6 +65,12 @@ android { } } +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(11)) + } +} + // how to configure the sentry android gradle plugin sentry { // Disables or enables the automatic configuration of Native symbols diff --git a/oem/firstvoices/android/build.sh b/oem/firstvoices/android/build.sh index e118afa875960b1d6fa8ff7af8571ce539147da0..75bcfc672a07ce01e6550c6191a1dddc6b119add 100755 --- a/oem/firstvoices/android/build.sh +++ b/oem/firstvoices/android/build.sh @@ -74,9 +74,6 @@ if builder_start_action clean; then fi if builder_start_action configure; then - # Copy Keyman Engine for Android - cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/${CONFIG}/keyman-engine.aar" "$KEYMAN_ROOT/oem/firstvoices/android/app/libs/keyman-engine.aar" - KEYBOARDS_CSV="$KEYMAN_ROOT/oem/firstvoices/keyboards.csv" KEYBOARDS_CSV_TARGET="$KEYMAN_ROOT/oem/firstvoices/android/app/src/main/assets/keyboards.csv" @@ -90,6 +87,9 @@ if builder_start_action configure; then fi if builder_start_action build; then + # Copy Keyman Engine for Android + cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar" "$KEYMAN_ROOT/oem/firstvoices/android/app/libs/keyman-engine.aar" + echo "BUILD_FLAGS: $BUILD_FLAGS" ./gradlew $DAEMON_FLAG clean $BUILD_FLAGS diff --git a/oem/firstvoices/android/gradle/wrapper/gradle-wrapper.properties b/oem/firstvoices/android/gradle/wrapper/gradle-wrapper.properties index 41dfb87909a877d96c3af4adccce4c7a301b55a2..ae04661ee733431762e7ccf8ab9b7409ed44960c 100644 --- a/oem/firstvoices/android/gradle/wrapper/gradle-wrapper.properties +++ b/oem/firstvoices/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/oem/firstvoices/ios/build_common.sh b/oem/firstvoices/ios/build_common.sh index 94e318ca7ee2a16ed937520409f3012bf22c1307..04c5ee24cec91cb2bb7592447b349fbb3d06ed30 100755 --- a/oem/firstvoices/ios/build_common.sh +++ b/oem/firstvoices/ios/build_common.sh @@ -154,7 +154,7 @@ if [ $DO_UPDATE = true ]; then fi # Copy resources. - cp -Rf "$KEYMAN_ENGINE_FRAMEWORK_SRC" "$KEYMAN_ENGINE_FRAMEWORK_DST" + /bin/cp -Rf "$KEYMAN_ENGINE_FRAMEWORK_SRC" "$KEYMAN_ENGINE_FRAMEWORK_DST" fi # First things first - update our dependencies. diff --git a/package-lock.json b/package-lock.json index fe82c29951bb1951ef68909373504d8d67804b4f..0f9caba307958d166889a3ae9538fdcb3ec4e915 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "resources/build/version", "core/include/ldml", "developer/src/kmc-keyboard", + "developer/src/kmc-kmn", "developer/src/kmc-model", "developer/src/kmc-model-info", "developer/src/kmc-package", @@ -871,6 +872,345 @@ "node": ">=0.3.1" } }, + "developer/src/kmc-kmn": { + "name": "@keymanapp/kmc-kmn", + "license": "MIT", + "dependencies": { + "@keymanapp/keyman-version": "*" + }, + "devDependencies": { + "@types/chai": "^4.1.7", + "@types/mocha": "^5.2.7", + "@types/node": "^10.14.6", + "@types/semver": "^7.3.12", + "@types/sinon": "^10.0.13", + "@types/sinon-chai": "^3.2.9", + "@types/xml2js": "^0.4.5", + "c8": "^7.12.0", + "chai": "^4.3.4", + "chalk": "^2.4.2", + "mocha": "^8.4.0", + "sinon": "^15.0.2", + "sinon-chai": "^3.7.0", + "ts-node": "^9.1.1", + "typescript": "^4.9.5" + } + }, + "developer/src/kmc-kmn/node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "developer/src/kmc-kmn/node_modules/@sinonjs/samsam": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "developer/src/kmc-kmn/node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "developer/src/kmc-kmn/node_modules/@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "dev": true + }, + "developer/src/kmc-kmn/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true + }, + "developer/src/kmc-kmn/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "developer/src/kmc-kmn/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "developer/src/kmc-kmn/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "developer/src/kmc-kmn/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "developer/src/kmc-kmn/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "developer/src/kmc-kmn/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "developer/src/kmc-kmn/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "developer/src/kmc-kmn/node_modules/mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "developer/src/kmc-kmn/node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "developer/src/kmc-kmn/node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "developer/src/kmc-kmn/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "developer/src/kmc-kmn/node_modules/nise": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "developer/src/kmc-kmn/node_modules/nise/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "developer/src/kmc-kmn/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "developer/src/kmc-kmn/node_modules/sinon": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.2.tgz", + "integrity": "sha512-PCVP63XZkg0/LOqQH5rEU4LILuvTFMb5tNxTHfs6VUMNnZz2XrnGSTZbAGITjzwQWbl/Bl/8hi4G3zZWjyBwHg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/samsam": "^7.0.1", + "diff": "^5.1.0", + "nise": "^5.1.4", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "developer/src/kmc-kmn/node_modules/sinon/node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "developer/src/kmc-kmn/node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "developer/src/kmc-kmn/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "developer/src/kmc-kmn/node_modules/supports-color/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "developer/src/kmc-kmn/node_modules/ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "developer/src/kmc-kmn/node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "developer/src/kmc-model": { "name": "@keymanapp/kmc-model", "license": "MIT", @@ -1833,6 +2173,10 @@ "resolved": "developer/src/kmc-keyboard", "link": true }, + "node_modules/@keymanapp/kmc-kmn": { + "resolved": "developer/src/kmc-kmn", + "link": true + }, "node_modules/@keymanapp/kmc-model": { "resolved": "developer/src/kmc-model", "link": true @@ -2264,6 +2608,24 @@ "type-detect": "4.0.8" } }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, + "node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, "node_modules/@sinonjs/formatio": { "version": "3.2.2", "dev": true, @@ -2481,6 +2843,31 @@ "@types/node": "*" } }, + "node_modules/@types/sinon": { + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinon-chai": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", + "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.3", "dev": true, @@ -7113,6 +7500,16 @@ "supports-color": "^5.5.0" } }, + "node_modules/sinon-chai": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "peerDependencies": { + "chai": "^4.0.0", + "sinon": ">=4.0.0" + } + }, "node_modules/sinon/node_modules/diff": { "version": "3.5.0", "dev": true, diff --git a/package.json b/package.json index e920ca12d739484269183df1ce6fa42aa369938c..071cd7a5e003e85939b277bee22891a8a2d97b00 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "resources/build/version", "core/include/ldml", "developer/src/kmc-keyboard", + "developer/src/kmc-kmn", "developer/src/kmc-model", "developer/src/kmc-model-info", "developer/src/kmc-package", diff --git a/resources/build/build-utils.md b/resources/build/build-utils.md index 16e1e7fce89985b15c04da4a155a9ab488c8fd1e..f6be8b3fc73a0fa4bba3bbe97f373ba503b21054 100644 --- a/resources/build/build-utils.md +++ b/resources/build/build-utils.md @@ -191,15 +191,27 @@ a user or called by another script: working on code within a dependency, you are currently expected to rebuild and test that dependency locally. - A dependency is similar to, but not the same as, a child project. Child + A module dependency is similar to, but not the same as, a child project. Child projects live in sub-folders of the parent project, whereas generally a dependency will be in another folder altogether. - Dependencies can be defined for all actions and targets, or may be limited to - specific action and/or targets. + Module dependencies can be defined for all actions and targets, or may be + limited to specific action and/or targets. - A dependency can be on a single target within a module, instead of all targets - within the module. + A module dependency can be on a single target within a module, instead of all + targets within the module. + + **Dependency definitions** + + It can be easy to confuse different dependency types! + + * An _external dependency_ is a dependency on a 3rd party component, which + typically needs to be downloaded during the `configure` stage of a script. + * An _internal dependency_ is a dependency within the current script + itself, such as `build` being internally dependent on `configure`. + * A dependency on another builder script, as described above, is called a + _module dependency_. + * _Child projects_ are not dependencies. But they can feel quite similar. The first step in your script is to describe the available parameters, using [`builder_describe`], for example: @@ -260,6 +272,25 @@ include. Use the longer form of `if ...; then` rather than the shorter `[ ... ] && ` pattern, for consistency and readability. +## Standard build script actions + +While no build script actions are pre-defined as such, there are a set of +standard actions that we should be using where possible. The actions should +be defined in the build script and 'actioned' in the order listed below. + +* `clean`: clean all artifacts. Running `clean` should generally be similar to + `git clean -fdx .`; the main difference is that user-created config files such + as codesigning controls would be kept. +* `configure`: install _external dependencies_, create build scripts where tools + require it. +* `build`: do the build. note: if _module dependency_ artifacts must be copied + or transformed at any stage, this should be done in the `build` action. +* `test`: run automated unit tests. Some e2e tests may run here, so long as they + have no UX impact -- i.e. we should not run e2e tests that take over the + system keyboard or emit key events by default. +* `install`: install the built artifact on the local system for use. +* `publish`: publish the built artifacts to relevant repositories. + # Internal dependencies All build scripts have a set of automatic internal dependencies: diff --git a/resources/build/build-utils.sh b/resources/build/build-utils.sh index f29ea4c0f02b86056ce63b30742aa881b4f2e572..1cad37a34f7c4fee8d9e18de7eba53f55f72f9ab 100755 --- a/resources/build/build-utils.sh +++ b/resources/build/build-utils.sh @@ -287,6 +287,15 @@ set_keyman_standard_build_path() { PATH="$KEYMAN_ROOT/node_modules/.bin:$PATH" } +# For CI compatbility of building Keyman for Android 16.0 with OpenJDK 8, +# this overrides JAVA_HOME for the builder script to use OpenJDK 11. +set_java_home() { + if [[ ! -z {$JAVA_HOME_11+x} ]]; then + builder_echo "Setting JAVA_HOME to JAVA_HOME_11 ($JAVA_HOME_11)" + export JAVA_HOME="${JAVA_HOME_11}" + fi +} + # # printXCodeBuildScriptLogs: xcodebuild does not emit stdout from scripts in # PBXShellScriptBuildPhase phases. This is a real problem for us because if diff --git a/resources/build/meson/standard.meson.build b/resources/build/meson/standard.meson.build new file mode 100644 index 0000000000000000000000000000000000000000..87efed5ab55cbd06ae642324f54ed9ba1f6d3f56 --- /dev/null +++ b/resources/build/meson/standard.meson.build @@ -0,0 +1,86 @@ +# +# Shared configuration for all meson-based builds +# +# This file has the master location /resources/build/meson/standard.meson.build, +# and is copied into each project's /resources/meson.build in the +# configure step, so that it can be referenced by meson directly. +# +# Where possible, we want to use these flags everywhere +# + +cpp_compiler = meson.get_compiler('cpp') +c_compiler = meson.get_compiler('c') + +# Once we can assume meson 0.60 we can delete this +# (https://mesonbuild.com/Release-notes-for-0-60-0.html#msvc-compiler-now-assumes-utf8-source-code-by-default) +if cpp_compiler.get_id() == 'msvc' + add_global_arguments('/source-charset:utf-8', language: ['c', 'cpp']) +endif + +# +# Standard informational messages for our builds +# + +message('meson.project_version(): ' + meson.project_version()) +message('host_machine.system(): ' + host_machine.system()) +message('compiler.get_id(): ' + cpp_compiler.get_id()) + +# +# Standard compiler flags for all platforms +# + +warns = [] +flags = [] +links = [] +defns = [] + +if cpp_compiler.get_id() == 'gcc' or cpp_compiler.get_id() == 'clang' + warns += [ + '-Wctor-dtor-privacy', + '-Wdouble-promotion', + '-Wendif-labels', + '-Wno-unknown-pragmas', + '-Wno-missing-field-initializers', + '-Wnon-virtual-dtor', + '-Wshadow' + ] + flags += [ + '-fvisibility=hidden', + '-fvisibility-inlines-hidden' + ] + + if cpp_compiler.get_id() == 'clang' + warns += [ + '-Wimplicit-fallthrough', + '-Wno-double-promotion', + '-Wshorten-64-to-32' + ] + endif + + if host_machine.system() == 'darwin' + # TODO: this seems to be inverting above options, is this necessary, or can + # we resolve another way? + warns += [ + '-Wno-ctor-dtor-privacy', + '-Wno-non-virtual-dtor' + ] + endif +endif + +if cpp_compiler.get_id() == 'msvc' + defns += [ + '-D_SCL_SECURE_NO_WARNINGS', + '-D_CRT_SECURE_NO_WARNINGS' + ] +endif + +if cpp_compiler.get_id() == 'emscripten' + if get_option('buildtype') == 'debug' + # Enable DWARF symbols for debug builds + flags += ['-g'] + links += ['-g'] + else + flags += ['-O2'] + links += ['-O2'] + endif +endif diff --git a/resources/build/npm-publish.inc.sh b/resources/build/npm-publish.inc.sh deleted file mode 100644 index e0e5ca5e313b3157cf720e38a7f0e1d18c6030c1..0000000000000000000000000000000000000000 --- a/resources/build/npm-publish.inc.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -# -# This script requires builder.inc.sh to already be included -# - -function npm_publish() { - if [[ $TIER == stable ]]; then - npm_dist_tag=latest - else - npm_dist_tag=$TIER - fi - - set_npm_version - - if builder_has_option --dry-run; then - DRY_RUN=--dry-run - else - DRY_RUN= - fi - - # Note: In either case, npm publish MUST be given --access public to publish - # a package in the @keymanapp scope on the public npm package index. - # - # See `npm help publish` for more details. - echo "Publishing $DRY_RUN npm package with tag $npm_dist_tag" - npm publish $DRY_RUN --access public --tag $npm_dist_tag || builder_die "Could not publish $npm_dist_tag release." -} diff --git a/tsconfig.esm.json b/tsconfig.esm.json index 412d6d4b500eb5d0ad6655abec18c31ed84b43f1..d8a5bf5432500224d444d8d8f491ff73608557dd 100644 --- a/tsconfig.esm.json +++ b/tsconfig.esm.json @@ -12,6 +12,8 @@ { "path": "./developer/src/kmc-keyboard/test/tsconfig.json" }, { "path": "./developer/src/kmc-keyboard/tsconfig.json" }, + { "path": "./developer/src/kmc-kmn/test/tsconfig.json" }, + { "path": "./developer/src/kmc-kmn/tsconfig.json" }, { "path": "./developer/src/kmc-model/test/tsconfig.json" }, { "path": "./developer/src/kmc-model/tsconfig.json" }, //{ "path": "./developer/src/kmc-model-info/test/tsconfig.json" }, diff --git a/web/src/app/browser/src/contextManager.ts b/web/src/app/browser/src/contextManager.ts index a92f0b44735824eced7f76fda589f7cab396520a..170a9a79183e8b315051ca802579f54bd7ffbb3f 100644 --- a/web/src/app/browser/src/contextManager.ts +++ b/web/src/app/browser/src/contextManager.ts @@ -82,7 +82,7 @@ export default class ContextManager extends ContextManagerBase { * affect only the specified `target`. */ protected get keyboardTarget(): OutputTarget { - // Remove `&& false` once the inlined section below is implemented. + // TODO: Remove `&& false` once the inlined section below is implemented. if(this.activeTarget /* has 'independent keyboard mode activated' */ && false) { return this.activeTarget; } else { diff --git a/web/src/app/webview/src/contextManager.ts b/web/src/app/webview/src/contextManager.ts index 8e6d4901f94bfa65aa5b275153fa04fdb66ea6b3..131590b0b3709b26faaebb397b34331a04338242 100644 --- a/web/src/app/webview/src/contextManager.ts +++ b/web/src/app/webview/src/contextManager.ts @@ -93,8 +93,11 @@ export default class ContextManager extends ContextManagerBase { kbd.refreshLayouts() diff --git a/web/src/engine/main/src/contextManagerBase.ts b/web/src/engine/main/src/contextManagerBase.ts index eda37eb3a5e372ca99f80efccd2a6c51aafe96c5..6f39957369167d0f452d45839a629db3d311d3cc 100644 --- a/web/src/engine/main/src/contextManagerBase.ts +++ b/web/src/engine/main/src/contextManagerBase.ts @@ -9,19 +9,15 @@ interface EventMap { 'targetchange': (target: OutputTarget) => boolean; /** - * This event is raised whenever a keyboard change is requested. Calling the second parameter - - * `abortChange` - will abort the process and prevent the change. + * This event is raised whenever a keyboard change is requested. * * Note that if the keyboard has not been previously loaded, this event will be raised twice. * 1. Before the keyboard is loaded into Keyman Engine for Web. - * - Aborting at this point will prevent the keyboard from being loaded, with no network - * request for the keyboard resource being triggered. * 2. Once the keyboard is loaded, but before it is activated. * @param metadata The to-be-activated keyboard's properties - * @param abortChange A functor that cancels the pending keyboard change when called * @returns */ - 'beforekeyboardchange': (metadata: KeyboardStub, abortChange: () => void) => void; + 'beforekeyboardchange': (metadata: KeyboardStub) => void; /** * This event is raised whenever an activating keyboard is being loaded into Keyman Engine for @@ -161,22 +157,6 @@ export abstract class ContextManagerBase return this.pendingActivations.splice(activationIndex, 1)[0]; } - /** - * Triggers a `beforekeyboardchange` event that allows its consumers to cancel a change of - * keyboard if desired. - * @param metadata The keyboard properties for the potentially-activating keyboard - * @returns `false` if the change should be cancelled; otherwise, `true`. - */ - protected confirmKeyboardChange(metadata: KeyboardStub): boolean { - const eventReturn = { - continue: true - }; - - this.emit('beforekeyboardchange', metadata, () => {eventReturn.continue = false}); - - return eventReturn.continue; - } - /** * Internally registers a pending keyboard-activation's properties, only resolving to a non-null * activation if it is still the most recent keyboard-activation request that would affect the @@ -242,13 +222,13 @@ export abstract class ContextManagerBase * - if a keyboard was asynchronously loaded for this... * - it is possible for the context (in app/browser) to have changed to a page element in * "independent keyboard" mode (or away from one) - * - This is the second `beforeKeyboardChange` check - a loaded keyboard may now be activated. + * - This is the "second" `beforeKeyboardChange` call - a loaded keyboard may now be activated. * * If the now-current context would be unaffected by the keyboard change, we do not raise the corresponding * event. */ - if(this.keyboardTarget == originalKeyboardTarget && !this.confirmKeyboardChange(activatingKeyboard.metadata)) { - return false; + if(this.keyboardTarget == originalKeyboardTarget) { + this.emit('beforekeyboardchange', activatingKeyboard.metadata); } this.setKeyboardActiveForTarget({ @@ -320,15 +300,8 @@ export abstract class ContextManagerBase } else { // It's async time - the keyboard is not preloaded within the cache. Use the stub's data to load it. - // `beforeKeyboardChange` - first check - // If the user cancels here, we prevent the network request that would load the keyboard from - // being triggered. - if(!this.confirmKeyboardChange(requestedStub)) { - return { - keyboard: Promise.resolve(null), - metadata: requestedStub - } - } + // `beforeKeyboardChange` - first call + this.emit('beforekeyboardchange', requestedStub); const defermentPromise = this.engineConfig.deferForInitialization.corePromise.then(() => { // Provide a Promise for completion of the async load process. diff --git a/web/src/test/manual/web/options-with-save/options_with_save.js b/web/src/test/manual/web/options-with-save/options_with_save.js index 301ae1c673b602780a26ed0c71215fae44ccfbf7..d62f2f3d9f3e3305bd828f116517f1f456495389 100644 --- a/web/src/test/manual/web/options-with-save/options_with_save.js +++ b/web/src/test/manual/web/options-with-save/options_with_save.js @@ -1,4 +1,4 @@ -// Original source may be found within the repo at /core/tests/unit/kmx/ as #023. +// Original source may be found within the repo at /common/test/keyboards/baseline as #023. if(typeof keyman === 'undefined') { console.log('Keyboard requires KeymanWeb 10.0 or later'); diff --git a/windows/src/Makefile b/windows/src/Makefile index 5ff33a3fb1b91b2404a61c20a016259d877da89c..7dda8852632cd40ce8698fea856d16de4352aeaa 100644 --- a/windows/src/Makefile +++ b/windows/src/Makefile @@ -276,7 +276,7 @@ build-tools: global-versions: cd $(COMMON_ROOT) - @if not exist $(KEYMAN_ROOT)\common\windows\cpp\include\keymanversion_build.h $(MAKE) global-versions + @if not exist $(KEYMAN_ROOT)\include\keymanversion_build.h $(MAKE) global-versions cd $(ROOT)\src message-constants: build-tools diff --git a/windows/src/Target.mak b/windows/src/Target.mak index 42ec5a492379297cf1cae1752442fb9abd65df3c..f115f5ac044512c52f0807c9bb64d4f8ebfcbe8a 100644 --- a/windows/src/Target.mak +++ b/windows/src/Target.mak @@ -17,7 +17,7 @@ versionhistory-app2: devtools-app: dirs cd $(COMMON_ROOT) - @if not exist $(KEYMAN_ROOT)\common\windows\cpp\include\keymanversion_build.h $(MAKE) global-versions + @if not exist $(KEYMAN_ROOT)\include\keymanversion_build.h $(MAKE) global-versions cd $(COMMON_ROOT)\tools\devtools $(MAKE) cd $(ROOT)\src diff --git a/windows/src/desktop/kmshell/kmshell.res b/windows/src/desktop/kmshell/kmshell.res index d1da4f0dc81a6eaccbd40b44f73fc727cd8a11f6..cfcbd309f137d6a5f5221aba48a1c759c0d56682 100644 Binary files a/windows/src/desktop/kmshell/kmshell.res and b/windows/src/desktop/kmshell/kmshell.res differ diff --git a/windows/src/desktop/kmshell/xml/config.css b/windows/src/desktop/kmshell/xml/config.css index 1bc4fdd3551eee27817395c1d668413bf8bc606f..f38c55a2963661c87387f8fd51a4cccee8fb34bd 100644 --- a/windows/src/desktop/kmshell/xml/config.css +++ b/windows/src/desktop/kmshell/xml/config.css @@ -1199,8 +1199,8 @@ th .list_languages_add { padding-top: 10px; position: fixed; - top: 45%; - left: 49%; + top: 223px; /* Have to use fixed position can't use flex or grid inside a fixed child */ + right: 281px; } .modify .keyboard_language { diff --git a/windows/src/global/Makefile b/windows/src/global/Makefile index 907a0235c53589b4fa583332003e7656e7141eb1..081a907cfbc0cdc91956b6d60e274b701fb98aa8 100644 --- a/windows/src/global/Makefile +++ b/windows/src/global/Makefile @@ -20,7 +20,7 @@ build-release: clean: -del $(ROOT)\src\global\delphi\general\keymanversion_build.inc - -del $(KEYMAN_ROOT)\common\windows\cpp\include\keymanversion_build.h + $(GIT_BASH_FOR_KEYMAN) $(KEYMAN_ROOT)/common/include/build.sh clean cd $(ROOT)\src\global\delphi $(MAKE) clean