chore(common/models): Merge branch 'refactor/common/models/suggestion-and-keep-init' into fix/common/models/suggestions-after-whitespace

This commit is contained in:
jahorton 2020-10-06 12:49:44 +07:00
commit 3bad0d18da
79 changed files with 2870 additions and 2293 deletions

View file

@ -1,5 +1,20 @@
# Keyman Version History
## 14.0.154 alpha 2020-10-05
* fix(windows): Upgrading keyboards with transient profiles (#3637)
* fix(windows): upgrading disabled keyboards (#3638)
* fix(developer): coverity reports for compiler (#3640)
* fix(windows): coverity reports for mcompile (#3641)
* fix(windows): coverity reports for kmtip (#3642)
* fix(windows): coverity reports for keyman32 (#3649)
* chore: exclude parens if no scope in commit msg (#3653)
## 14.0.153 alpha 2020-10-02
* chore(deps): bump @actions/core from 1.2.2 to 1.2.6 in /resources/build/version (#3646)
* fix(android/app): Switch system keyboard in KMPBrowserActivity (#3648)
## 14.0.152 alpha 2020-09-30
* fix(ios/engine): package installation language-picker improvements (#3623)

View file

@ -1 +1 @@
14.0.153
14.0.155

View file

@ -16,15 +16,18 @@ import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.tavultesoft.kmea.KMManager;
import com.tavultesoft.kmea.KeyboardEventHandler;
import com.tavultesoft.kmea.util.KMPLink;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class KMPBrowserActivity extends AppCompatActivity {
public class KMPBrowserActivity extends AppCompatActivity implements KeyboardEventHandler.OnKeyboardEventListener {
private static final String TAG = "KMPBrowserActivity";
// URL for keyboard search web page presented to user when they add a keyboard in the app.
@ -133,6 +136,8 @@ public class KMPBrowserActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
KMManager.addKeyboardEventListener(this);
if (webView != null) {
webView.reload();
}
@ -141,6 +146,7 @@ public class KMPBrowserActivity extends AppCompatActivity {
@Override
protected void onPause() {
super.onPause();
KMManager.removeKeyboardEventListener(this);
}
@Override
@ -148,6 +154,32 @@ public class KMPBrowserActivity extends AppCompatActivity {
super.onDestroy();
}
@Override
public void onKeyboardLoaded(KMManager.KeyboardType keyboardType) {
// Mitigation for https://github.com/keymanapp/keyman/issues/1963
// Due to latency, switch from Keyman system keyboard to another
if (KMManager.getKMKeyboard(KMManager.KeyboardType.KEYBOARD_TYPE_SYSTEM) != null) {
Toast.makeText(getApplicationContext(), getString(R.string.switching_keyboard),
Toast.LENGTH_SHORT).show();
KMManager.advanceToNextInputMode();
}
}
@Override
public void onKeyboardChanged(String newKeyboard) {
// Do nothing
}
@Override
public void onKeyboardShown() {
//
}
@Override
public void onKeyboardDismissed() {
// Do nothing
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

View file

@ -112,6 +112,8 @@
<!-- Context: Keyman Settings "Install Keyboard or Dictionary" menu -->
<string name="add_language_subtext" comment="Additional information for adding another language">(from keyboard package)</string>
<!-- Context: Keyman Settings "Install from keyman.com" menu -->
<string name="switching_keyboard" comment="Switching to another keyboard">Switching to another keyboard</string>
<!-- Context: Select Package and Select Languages menu -->
<string name="title_select_keyboard_package_list" comment="Select a keyboard package to add languages">Select Keyboard Package</string>

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/input-processor",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/input-processor",
"version": "14.0.153",
"version": "14.0.155",
"description": "The core text and prediction processing engine for KeymanWeb",
"repository": {
"type": "git",
@ -18,7 +18,7 @@
},
"homepage": "https://github.com/keymanapp/keyman#readme",
"devDependencies": {
"@keymanapp/resources-gosh": "^14.0.153",
"@keymanapp/resources-gosh": "^14.0.155",
"chai": "^4.2.0",
"mocha": "^5.2.0",
"typescript": "^3.8.3"
@ -29,11 +29,11 @@
"test": "gosh ./unit_tests/test.sh"
},
"dependencies": {
"@keymanapp/keyboard-processor": "^14.0.153",
"@keymanapp/lexical-model-layer": "^14.0.153",
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/web-environment": "^14.0.153",
"@keymanapp/web-utils": "^14.0.153",
"@keymanapp/keyboard-processor": "^14.0.155",
"@keymanapp/lexical-model-layer": "^14.0.155",
"@keymanapp/models-types": "^14.0.155",
"@keymanapp/web-environment": "^14.0.155",
"@keymanapp/web-utils": "^14.0.155",
"@types/node": "^11.9.4",
"eventemitter3": "^4.0.0",
"ts-node": "^8.0.2"

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/keyboard-processor",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/keyboard-processor",
"version": "14.0.153",
"version": "14.0.155",
"description": "Core module for Keyman keyboard support in KeymanWeb.",
"repository": {
"type": "git",
@ -18,7 +18,7 @@
},
"homepage": "https://github.com/keymanapp/keyman#readme",
"devDependencies": {
"@keymanapp/resources-gosh": "^14.0.153",
"@keymanapp/resources-gosh": "^14.0.155",
"chai": "^4.2.0",
"mocha": "^5.2.0",
"mocha-teamcity-reporter": "^3.0.0",
@ -31,9 +31,9 @@
"mocha": "mocha"
},
"dependencies": {
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/web-environment": "^14.0.153",
"@keymanapp/web-utils": "^14.0.153",
"@keymanapp/models-types": "^14.0.155",
"@keymanapp/web-environment": "^14.0.155",
"@keymanapp/web-utils": "^14.0.155",
"@types/node": "^11.9.4",
"ts-node": "^8.0.2"
}

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/recorder-core",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/recorder-core",
"version": "14.0.153",
"version": "14.0.155",
"description": "Core classes used to develop KeymanWeb test cases based on keystrokes",
"main": "index.js",
"scripts": {
@ -17,10 +17,10 @@
},
"homepage": "https://github.com/keymanapp/keyman#readme",
"dependencies": {
"@keymanapp/keyboard-processor": "^14.0.153",
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/web-environment": "^14.0.153",
"@keymanapp/web-utils": "^14.0.153"
"@keymanapp/keyboard-processor": "^14.0.155",
"@keymanapp/models-types": "^14.0.155",
"@keymanapp/web-environment": "^14.0.155",
"@keymanapp/web-utils": "^14.0.155"
},
"devDependencies": {
"typescript": "^3.8.3"

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/web-sentry-manager",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/web-sentry-manager",
"version": "14.0.153",
"version": "14.0.155",
"description": "Common setup for KeymanWeb's Sentry-based error reporting",
"main": "dist/index.js",
"scripts": {
@ -20,7 +20,7 @@
"typescript": "^3.8.3"
},
"dependencies": {
"@keymanapp/web-environment": "^14.0.153",
"@keymanapp/web-environment": "^14.0.155",
"@sentry/browser": "^5.15.5"
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/web-utils",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/web-utils",
"version": "14.0.153",
"version": "14.0.155",
"description": "Common utility functions used throughout other Keyman packages",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@ -20,8 +20,8 @@
},
"homepage": "https://github.com/keymanapp/keyman#readme",
"devDependencies": {
"@keymanapp/resources-gosh": "^14.0.153",
"@keymanapp/web-environment": "^14.0.153",
"@keymanapp/resources-gosh": "^14.0.155",
"@keymanapp/web-environment": "^14.0.155",
"@types/node": "^14.0.5",
"typescript": "^3.8.3"
}

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/models-templates",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/models-templates",
"version": "14.0.153",
"version": "14.0.155",
"description": "Backing model implementations (templates) for Keyman's modelling layer",
"keywords": [
"lm",
@ -42,8 +42,8 @@
"url": "https://github.com/keymanapp/keyman/issues"
},
"devDependencies": {
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/web-utils": "^14.0.153",
"@keymanapp/models-types": "^14.0.155",
"@keymanapp/web-utils": "^14.0.155",
"@types/chai": "^4.2.11",
"@types/mocha": "^7.0.2",
"@types/node": "^14.0.4",
@ -52,6 +52,6 @@
"typescript": "^3.8.3"
},
"dependencies": {
"@keymanapp/models-wordbreakers": "^14.0.153"
"@keymanapp/models-wordbreakers": "^14.0.155"
}
}

View file

@ -71,11 +71,15 @@ namespace models {
export function transformToSuggestion(transform: Transform): Suggestion;
export function transformToSuggestion(transform: Transform, p: number): Suggestion & {p: number};
export function transformToSuggestion(transform: Transform, p?: number): Suggestion & {p?: number} {
return {
let suggestion: Suggestion & {p?: number} = {
transform: transform,
transformId: transform.id,
displayAs: transform.insert,
p: p
displayAs: transform.insert
};
if(p === 0 || p) {
suggestion.p = p;
}
return suggestion;
}
}

View file

@ -1,4 +1,5 @@
/// <reference path="./trie-model.ts" />
/// <reference path="./quote-behavior.ts" />
// Add all namespaces defined here to the global scope:
if (typeof module != 'undefined' && typeof module.exports != 'undefined') {

View file

@ -0,0 +1,46 @@
namespace models {
export enum QuoteBehavior {
noQuotes = "no-quotes",
useQuotes = "use-quotes",
default = "default-quotes"
}
// For an "enum/namespace merge". See https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-namespaces-with-classes
export namespace QuoteBehavior {
/**
* Applies the specified quote behavior to the provided `Transform`, mutating it as appropriate.
* @param transform The Transform to be mutated
* @param punctuation The active `LexicalModelPunctuation` settings
* @param defaultTo The default quote behavior to use (in case the current value is `.default`)
*/
export function apply(behavior: QuoteBehavior, text: string, punctuation: LexicalModelPunctuation, defaultTo: QuoteBehavior): string {
if(defaultTo == QuoteBehavior.default || !defaultTo) {
throw "Specified quote behavior may be ambiguous - default behavior not specified (may not be .default)";
}
if(behavior == QuoteBehavior.default) {
behavior = defaultTo;
}
switch(behavior) {
case QuoteBehavior.noQuotes:
return text;
case QuoteBehavior.useQuotes:
let {open, close} = punctuation.quotesForKeepSuggestion;
// TODO: Is this the right thing to do under RTL?
// We need an extra pass over this section to validate it.
if(punctuation.isRTL) {
let temp = close;
close = open;
open = temp;
}
// This part's simple enough, at least.
return open + text + close;
default:
throw "Unsupported quote behavior state detected; implementation missing!";
}
}
}
}

View file

@ -0,0 +1,70 @@
/*
* Unit tests for common utility functions/methods.
*/
var assert = require('chai').assert;
var models = require('../').models;
describe('Common utility functions', function() {
// TODO: unit tests for other common utility functions
describe('transformToSuggestion', function() {
it('p: undefined', function() {
let suggestion = {
transform: {
insert: 'hello',
deleteLeft: 0,
id: 0
},
transformId: 0,
displayAs: 'hello'
};
assert.deepEqual(models.transformToSuggestion(suggestion.transform), suggestion);
});
it('p: 0', function() {
let suggestion = {
transform: {
insert: 'hello',
deleteLeft: 0,
id: 0
},
transformId: 0,
displayAs: 'hello',
p: 0
};
assert.deepEqual(models.transformToSuggestion(suggestion.transform, 0), suggestion);
});
it('p > 0', function() {
let suggestion = {
transform: {
insert: 'hello',
deleteLeft: 0,
id: 0
},
transformId: 0,
displayAs: 'hello',
p: 0.5
};
assert.deepEqual(models.transformToSuggestion(suggestion.transform, 0.5), suggestion);
});
it('properly handles the transformId', function() {
let suggestion = {
transform: {
insert: 'hello',
deleteLeft: 0,
id: 3
},
transformId: 3, // Ensures there isn't a separate ID seed in use.
displayAs: 'hello'
};
assert.deepEqual(models.transformToSuggestion(suggestion.transform), suggestion);
});
});
});

View file

@ -0,0 +1,150 @@
/*
* Unit tests for quote behaviors.
*/
var assert = require('chai').assert;
var QuoteBehavior = require('../').models.QuoteBehavior;
describe('Quote behaviors', function() {
describe('Script directionality', function() {
it('(default)', function() {
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: " "
}
var plainQuotedHello;
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
assert.equal(plainQuotedHello, "“hello”");
});
it('LTR', function() {
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: " ",
isRTL: false
}
var plainQuotedHello;
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
assert.equal(plainQuotedHello, "“hello”");
});
it.skip('RTL', function() {
// TODO:
});
});
describe('Application', function() {
it('.useQuotes', function() {
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: " "
}
var plainQuotedHello;
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
assert.equal(plainQuotedHello, "“hello”");
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.noQuotes);
assert.equal(plainQuotedHello, "“hello”");
let angleQuotePunctuation = {
quotesForKeepSuggestion: { open: `«`, close: `»`},
insertAfterWord: " "
}
var angleQuotedHello;
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes);
assert.equal(angleQuotedHello, "«hello»");
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes);
assert.equal(angleQuotedHello, "«hello»");
});
it('.noQuotes', function() {
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: " "
}
var plainQuotedHello;
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.useQuotes);
assert.equal(plainQuotedHello, "hello");
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.noQuotes);
assert.equal(plainQuotedHello, "hello");
let angleQuotePunctuation = {
quotesForKeepSuggestion: { open: `«`, close: `»`},
insertAfterWord: " "
}
var angleQuotedHello;
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes);
assert.equal(angleQuotedHello, "hello");
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes);
assert.equal(angleQuotedHello, "hello");
});
it('.default -> .useQuotes', function() {
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: " "
}
var plainQuotedHello;
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.useQuotes);
assert.equal(plainQuotedHello, "“hello”");
let angleQuotePunctuation = {
quotesForKeepSuggestion: { open: `«`, close: `»`},
insertAfterWord: " "
}
var angleQuotedHello;
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", angleQuotePunctuation, QuoteBehavior.useQuotes);
assert.equal(angleQuotedHello, "«hello»");
});
it('.default -> .noQuotes', function() {
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: " "
}
var plainQuotedHello;
plainQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.noQuotes);
assert.equal(plainQuotedHello, "hello");
let angleQuotePunctuation = {
quotesForKeepSuggestion: { open: `«`, close: `»`},
insertAfterWord: " "
}
var angleQuotedHello;
angleQuotedHello = QuoteBehavior.apply(QuoteBehavior.default, "hello", angleQuotePunctuation, QuoteBehavior.noQuotes);
assert.equal(angleQuotedHello, "hello");
});
it('Error case: .default as fall-back behavior', function() {
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: " "
}
assert.throws(function() {
QuoteBehavior.apply(QuoteBehavior.default, "hello", englishPunctuation, QuoteBehavior.default);
});
assert.throws(function() {
QuoteBehavior.apply(QuoteBehavior.useQuotes, "hello", englishPunctuation, QuoteBehavior.default);
});
assert.throws(function() {
QuoteBehavior.apply(QuoteBehavior.noQuotes, "hello", englishPunctuation, QuoteBehavior.default);
});
});
});
});

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/models-types",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/models-types",
"version": "14.0.153",
"version": "14.0.155",
"description": "Type definitions in used in the modeling (lexical model/predictive text) component of Keyman.",
"types": "./index.d.ts",
"scripts": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/models-wordbreakers",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/models-wordbreakers",
"version": "14.0.153",
"version": "14.0.155",
"description": "Word breakers bundled in the modeling layer",
"keywords": [
"lexical model",
@ -40,7 +40,7 @@
"url": "https://github.com/keymanapp/keyman/issues"
},
"devDependencies": {
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/models-types": "^14.0.155",
"@types/chai": "^4.2.11",
"@types/mocha": "^7.0.2",
"chai": "^4.2.0",

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/lexical-model-layer",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/lexical-model-layer",
"version": "14.0.153",
"version": "14.0.155",
"description": "Keyman/Predictive Text integration layer",
"main": "build/index.js",
"scripts": {
@ -21,8 +21,8 @@
},
"homepage": "https://github.com/keymanapp/keyman#readme",
"devDependencies": {
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/resources-gosh": "^14.0.153",
"@keymanapp/models-types": "^14.0.155",
"@keymanapp/resources-gosh": "^14.0.155",
"@types/node": "^10.17.21",
"chai": "^4.2.0",
"karma": "^4.2.0",
@ -46,10 +46,10 @@
"typescript": "^3.8.3"
},
"dependencies": {
"@keymanapp/models-templates": "^14.0.153",
"@keymanapp/models-wordbreakers": "^14.0.153",
"@keymanapp/web-environment": "^14.0.153",
"@keymanapp/web-utils": "^14.0.153",
"@keymanapp/models-templates": "^14.0.155",
"@keymanapp/models-wordbreakers": "^14.0.155",
"@keymanapp/web-environment": "^14.0.155",
"@keymanapp/web-utils": "^14.0.155",
"es6-shim": "^0.35.5",
"string.prototype.codepointat": "^0.2.1",
"string.prototype.startswith": "^0.2.0"

View file

@ -2,6 +2,8 @@
* Integration tests for the model compositor with the trie model.
*/
const { models } = require('../../build/intermediate');
var assert = require('chai').assert;
var TrieModel = require('../../build/intermediate').models.TrieModel;
var ModelCompositor = require('../../build/intermediate').ModelCompositor;
@ -66,4 +68,70 @@ describe('ModelCompositor', function() {
// 'the' should be the intended the result here.
assert.isAbove(theSuggestion.p, thrSuggestion.p);
});
// The nomenclature's a minor sneak-peek from child PRs.
describe('toAnnotatedSuggestion', function() {
let baseSuggestion = {
transform: {
insert: 'hello',
deleteLeft: 0,
id: 0
},
transformId: 0,
displayAs: 'hello'
};
let englishPunctuation = {
quotesForKeepSuggestion: { open: `“`, close: `”`},
insertAfterWord: ' '
};
let angledPunctuation = {
quotesForKeepSuggestion: { open: `«`, close: `»`},
insertAfterWord: " "
}
describe("'keep'", function() {
let annotationTest = function(punctuation, displayText, quoteStyle) {
let options = {
punctuation: punctuation
};
let model = new models.DummyModel(options);
let compositor = new ModelCompositor(model);
var keep;
if(quoteStyle) {
keep = compositor.toAnnotatedKeepSuggestion(baseSuggestion, quoteStyle);
} else {
keep = compositor.toAnnotatedKeepSuggestion(baseSuggestion);
}
// Make sure we didn't accidentally leak any mutations to the parameter.
assert.notDeepEqual(keep, baseSuggestion);
assert.equal(keep.displayAs, displayText);
assert.equal(keep.tag, 'keep');
}
it('quoteBehavior: (.default)', function() {
annotationTest(englishPunctuation, "“hello”");
annotationTest(angledPunctuation, "«hello»");
});
it('quoteBehavior: .useQuotes', function() {
annotationTest(englishPunctuation, "“hello”", models.QuoteBehavior.useQuotes);
annotationTest(angledPunctuation, "«hello»", models.QuoteBehavior.useQuotes);
});
it('quoteBehavior: .noQuotes', function() {
annotationTest(englishPunctuation, "hello", models.QuoteBehavior.noQuotes);
annotationTest(angledPunctuation, "hello", models.QuoteBehavior.noQuotes);
});
it.skip('RTL test', function() {
// TODO:
});
});
});
});

View file

@ -229,7 +229,7 @@ class ModelCompositor {
}
keepOption = models.transformToSuggestion(keepTransform, prediction.p);
keepOption = this.toAnnotatedKeepSuggestion(keepOption, true);
keepOption = this.toAnnotatedKeepSuggestion(keepOption, models.QuoteBehavior.noQuotes);
} else {
let existingSuggestion = suggestionDistribMap[displayText];
if(existingSuggestion) {
@ -296,25 +296,18 @@ class ModelCompositor {
return suggestions;
}
private toAnnotatedKeepSuggestion(suggestion: Suggestion & {p?: number}, noQuotes: boolean = false): Suggestion & {p?: number} {
let { open, close } = this.punctuation.quotesForKeepSuggestion;
if(noQuotes) {
open = '';
close = '';
} else if(this.punctuation.isRTL) {
let temp = close;
close = open;
open = temp;
}
private toAnnotatedKeepSuggestion(suggestion: Suggestion & {p?: number},
quoteBehavior: models.QuoteBehavior = models.QuoteBehavior.default): Suggestion & {p?: number} {
// A method-internal 'import' of the enum.
let QuoteBehavior = models.QuoteBehavior;
return {
transform: suggestion.transform,
transformId: suggestion.transformId,
displayAs: open + suggestion.displayAs + close,
displayAs: QuoteBehavior.apply(quoteBehavior, suggestion.displayAs, this.punctuation, QuoteBehavior.useQuotes),
tag: 'keep',
p: suggestion.p
}
};
}
/**

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/lexical-model-compiler",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/lexical-model-compiler",
"version": "14.0.153",
"version": "14.0.155",
"description": "Keyman Developer lexical model compiler",
"keywords": [
"keyboard",
@ -37,14 +37,14 @@
"node": ">=12.0.0"
},
"dependencies": {
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/models-types": "^14.0.155",
"commander": "^3.0.0",
"typescript": "^3.8.3",
"xml2js": "^0.4.19"
},
"devDependencies": {
"@keymanapp/models-templates": "^14.0.153",
"@keymanapp/models-wordbreakers": "^14.0.153",
"@keymanapp/models-templates": "^14.0.155",
"@keymanapp/models-wordbreakers": "^14.0.155",
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.7",
"@types/node": "^10.14.6",

View file

@ -16,5 +16,5 @@
"lerna",
"typescript"
],
"version": "14.0.153"
"version": "14.0.155"
}

View file

@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"@actions/core": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.2.tgz",
"integrity": "sha512-IbCx7oefq+Gi6FWbSs2Fnw8VkEI6Y4gvjrYprY3RV//ksq/KPMlClOerJ4jRosyal6zkUIc8R9fS/cpRMlGClg=="
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
},
"@actions/github": {
"version": "2.1.0",

View file

@ -1,6 +1,6 @@
{
"dependencies": {
"@actions/core": "^1.2.2",
"@actions/core": "^1.2.6",
"@actions/github": "^2.1.0",
"typescript": "^3.7.5",
"yargs": "^15.1.0"

View file

@ -96,7 +96,12 @@ function prepend_scope() {
else
postfix=""
fi
prefix="$TYPE($SCOPE): $EXTRA_WHITESPACE"
if [ -z "$SCOPE" ]; then
prefix="$TYPE: $EXTRA_WHITESPACE"
else
prefix="$TYPE($SCOPE): $EXTRA_WHITESPACE"
fi
# Reuse any existing message text, wrapping it in our conventional commit formatting before
# presenting it to the user for any final edits.

View file

@ -1,5 +1,5 @@
{
"name": "@keymanapp/resources-gosh",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1
}

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/resources-gosh",
"version": "14.0.153",
"version": "14.0.155",
"description": "Good Ol' Shell",
"author": "Marc Durdin <marc@keyman.com> (https://github.com/mcdurdin)",
"contributors": [

View file

@ -1,5 +1,5 @@
{
"name": "@keymanapp/web-environment",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1
}

View file

@ -1,6 +1,6 @@
{
"name": "@keymanapp/web-environment",
"version": "14.0.153",
"version": "14.0.155",
"description": "A compilation utility for passing select environment variables into our TS builds",
"author": "Joshua Horton <joshua_horton@sil.org> (https://github.com/jahorton)",
"homepage": "https://github.com/keymanapp/keyman",
@ -17,6 +17,6 @@
"url": "https://github.com/keymanapp/keyman/issues"
},
"devDependencies": {
"@keymanapp/resources-gosh": "^14.0.153"
"@keymanapp/resources-gosh": "^14.0.155"
}
}

2
web/package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "keyman",
"version": "14.0.153",
"version": "14.0.155",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "keyman",
"version": "14.0.153",
"version": "14.0.155",
"description": "Facilitates text input in any language.",
"repository": {
"type": "git",
@ -18,8 +18,8 @@
},
"homepage": "https://github.com/keymanapp/keyman#readme",
"devDependencies": {
"@keymanapp/resources-gosh": "^14.0.153",
"@keymanapp/web-sentry-manager": "^14.0.153",
"@keymanapp/resources-gosh": "^14.0.155",
"@keymanapp/web-sentry-manager": "^14.0.155",
"@sentry/cli": "^1.52.3",
"chai": "^4.2.0",
"google-closure-compiler-java": "^20200224.0.0",
@ -52,13 +52,13 @@
"sentry-cli": "sentry-cli"
},
"dependencies": {
"@keymanapp/input-processor": "^14.0.153",
"@keymanapp/keyboard-processor": "^14.0.153",
"@keymanapp/lexical-model-layer": "^14.0.153",
"@keymanapp/models-types": "^14.0.153",
"@keymanapp/recorder-core": "^14.0.153",
"@keymanapp/web-environment": "^14.0.153",
"@keymanapp/web-utils": "^14.0.153",
"@keymanapp/input-processor": "^14.0.155",
"@keymanapp/keyboard-processor": "^14.0.155",
"@keymanapp/lexical-model-layer": "^14.0.155",
"@keymanapp/models-types": "^14.0.155",
"@keymanapp/recorder-core": "^14.0.155",
"@keymanapp/web-environment": "^14.0.155",
"@keymanapp/web-utils": "^14.0.155",
"@types/node": "^11.9.4",
"es6-shim": "^0.35.5",
"eventemitter3": "^4.0.0",

View file

@ -193,6 +193,11 @@ test-uiaccess:
# * tar must be on path
#
!ifndef COVBUILD
test-coverity:
echo Set variable COVBUILD to covbuild.exe
exit 1
!else
test-coverity:
cd $(ROOT)\src
if exist cov-int rd /s/q cov-int
@ -218,6 +223,7 @@ test-coverity-internal:
$(MAKE) build
cd $(ROOT)\src\engine\mcompile
$(MAKE) build
!endif
# Build a release

View file

@ -32,6 +32,7 @@ uses
UImportOlderVersionKeyboards9Plus,
UImportOlderKeyboardUtils,
utilexecute,
utilkmshell,
utiltsf;
class procedure TImportOlderVersionKeyboards11To13.Execute; // I2361
@ -52,7 +53,7 @@ end;
type
TUpgradeKeyboard = record
KeyboardID: string;
LangID: Integer;
BCP47Code: string;
end;
TUpgradeKeyboardList = class(TList<TUpgradeKeyboard>);
@ -81,12 +82,9 @@ class procedure TImportOlderVersionKeyboards11To13.BackupCurrentUser;
r.GetKeyNames(profiles);
for profile in profiles do
begin
if r.OpenKeyReadOnly('\' + BuildKeyboardLanguageProfilesKey_LM(keyboard) + '\' + profile) and r.ValueExists(SRegValue_LanguageProfileLangID) then
begin
uk.KeyboardID := keyboard;
uk.LangID := r.ReadInteger(SRegValue_LanguageProfileLangID);
Result.Add(uk);
end;
uk.KeyboardID := keyboard;
uk.BCP47Code := profile;
Result.Add(uk);
end;
end;
end;
@ -101,19 +99,23 @@ var
r: TRegistry;
i: Integer;
uks: TUpgradeKeyboardList;
uk: TUpgradeKeyboard;
begin
// TODO: figure out Keyman "disabled" keyboards
// TODO: figure out transient language registrations
uks := LoadUpgradeKeyboards;
r := TRegistry.Create;
try
if not r.OpenKey(SRegKey_Keyman_Temp_BackupProfiles, True) then
Exit;
for i := 0 to uks.Count - 1 do
i := 0;
for uk in uks do
begin
r.WriteString(IntToStr(i), uks[i].KeyboardID+'='+IntToStr(uks[i].LangID));
// For transient language codes, we will need to install using an assigned id
// which may vary, so we will work from the BCP47 code.
r.WriteString(IntToStr(i), uk.KeyboardID+'='+uk.BCP47Code);
Inc(i);
end;
finally
r.Free;
uks.Free;
@ -170,6 +172,7 @@ begin
keys.Free;
end;
// The following code re-registers all the profiles
kmcom.Refresh;
(kmcom.Keyboards as IKeymanKeyboardsInstalled2).RefreshInstalledKeyboards;
end;
@ -180,6 +183,13 @@ var
strings: TStringList;
s: string;
p: TArray<string>;
BCP47Code, KeyboardID: string;
LangID: Integer;
kbd: IKeymanKeyboardInstalled;
lang: IKeymanKeyboardLanguageInstalled2;
TemporaryKeyboardID: WideString;
RegistrationRequired: WordBool;
i: Integer;
begin
r := TRegistry.Create;
strings := TStringList.Create;
@ -191,17 +201,94 @@ begin
for s in strings do
begin
// each string is saved in BackupCurrentUser and is keyboardid=langid
// each string is saved in BackupCurrentUser and is keyboardid=bcp47
p := r.ReadString(s).Split(['=']);
kmcom.Keyboards[p[0]].Languages.InstallByLangID(StrToInt(p[1]));
KeyboardID := p[0];
BCP47Code := p[1];
kbd := kmcom.Keyboards[KeyboardID];
if not Assigned(kbd) then
begin
// Avoid errors if a package is uninstalled midway through
Continue;
end;
// Installing a language is a 2-step process. (We can assume that
// the transient language codes have been installed correctly as Register
// would have been called immediately prior to this.)
lang := nil;
BCP47Code := (kmcom as IKeymanBCP47Canonicalization).GetCanonicalTag(BCP47Code);
for i := 0 to kbd.Languages.Count - 1 do
begin
if SameText(kbd.Languages[i].BCP47Code, BCP47Code) then
begin
lang := kbd.Languages[i] as IKeymanKeyboardLanguageInstalled2;
Break;
end;
end;
if lang = nil then
begin
// The BCP47 code was not in the list of languages; this could possibly
// happen if we had registered a code that was canonicalized differently
// in the past?
lang := (kbd.Languages as IKeymanKeyboardLanguagesInstalled2).Add(BCP47Code) as IKeymanKeyboardLanguageInstalled2;
if lang = nil then
begin
// This should never happen, because .Add only fails if the language
// is already in the list, which we just searched through, or if the
// BCP47Code is empty
Continue;
end;
end;
if lang.IsInstalled then
begin
// Don't attempt to reinstall; this should not normally be the case but
// if we canonicalize two languages which were previously installed into
// a single code, then in theory this could happen.
Continue;
end;
if lang.FindInstallationLangID(LangID, TemporaryKeyboardID, RegistrationRequired, kifInstallTransientLanguage) then
begin
if RegistrationRequired then
begin
// This can happen for custom language codes. TODO: This is not ideal because of potential for multiple elevation prompts
WaitForElevatedConfiguration(0, '-register-tip '+IntToHex(LangID,4)+' "'+KeyboardID+'" "'+lang.BCP47Code+'"');
end;
lang.InstallTip(LangID, TemporaryKeyboardID);
end;
end;
r.CloseKey;
r.DeleteKey(SRegKey_Keyman_Temp_BackupProfiles);
//
// Reapply the loaded state for keyboards; this may cause TIPs to disappear again
//
kmcom.Refresh;
if r.OpenKeyReadOnly('\' + SRegKey_ActiveKeyboards_CU) then
begin
strings.Clear;
r.GetKeyNames(strings);
for s in strings do
begin
kbd := kmcom.Keyboards[s];
if Assigned(kbd) then
kbd.Loaded := r.OpenKeyReadOnly('\' + SRegKey_ActiveKeyboards_CU + '\' + s) and r.ValueExists(SRegValue_KeymanID);
end;
end;
finally
strings.Free;
r.Free;
end;
kmcom.Apply;
kmcom.Refresh;
end;
end.

File diff suppressed because it is too large Load diff

View file

@ -172,18 +172,23 @@ BOOL NamedCodeConstants::LoadFile(const char *filename)
void NamedCodeConstants::reindex()
{
qsort(entries, nEntries, sizeof(NCCENTRY), sort_entries);
if (entries != NULL) {
qsort(entries, nEntries, sizeof(NCCENTRY), sort_entries);
}
char c = '.', d;
int i;
for(i = 0; i < 128; i++) chrindexes[i] = -1;
for(i = 0; i < nEntries; i++)
{
d = toupper(entries[i].name[0]);
if(d != c && d >= 32 && d <= 127)
chrindexes[c = d] = i;
}
if (entries != NULL) {
for (i = 0; i < nEntries; i++)
{
d = toupper(entries[i].name[0]);
if (d != c && d >= 32 && d <= 127)
chrindexes[c = d] = i;
}
}
}
int NamedCodeConstants::GetCode(const char *codename, DWORD *storeIndex)

View file

@ -28,7 +28,7 @@
int WINAPI msgproc(int line, DWORD dwMsgCode, LPSTR szText)
{
printf("line %d error %x %s\n", line, dwMsgCode, szText);
printf("line %d error %x %s\n", line, (unsigned int) dwMsgCode, szText);
return 1;
}

View file

@ -5,8 +5,8 @@
BOOL AddCompileString(LPSTR buf);
BOOL AddCompileMessage(DWORD msg);
#define SetError(err) { if(AddCompileMessage(err)) return FALSE; }
#define SetError(err) { if(AddCompileMessage(err) || (err & (CERR_MEMORY|CERR_FATAL))) return FALSE; }
#define AddWarning(warn) { if(AddCompileMessage(warn)) return FALSE; }
extern BOOL FWarnDeprecatedCode;
extern int currentLine;
extern int currentLine;

View file

@ -12,7 +12,7 @@ BOOL CheckKeyboardFinalVersion(PFILE_KEYBOARD fk) {
fk->version = VERSION_60; // minimum version that we can be safe with
}
wsprintf(buf, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (fk->version & 0xFF00) >> 8, fk->version & 0xFF);
wsprintf(buf, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (int)((fk->version & 0xFF00) >> 8), (int)(fk->version & 0xFF));
AddCompileString(buf);
}

View file

@ -68,7 +68,7 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i
WCHAR windowinfo[1024];
wsprintfW(windowinfo,
DEBUG_PLATFORM_STRINGW TAB //"Platform" TAB
L"%s" TAB //"Process" TAB
L"%ls" TAB //"Process" TAB
L"%x" TAB //"PID" TAB
L"%x" TAB //"TID" TAB
L"%x" TAB //"ShiftState" TAB
@ -77,15 +77,15 @@ extern "C" void _declspec(dllexport) WINAPI Keyman_WriteDebugEvent(char *file, i
L"%x" TAB //"FocusHWND" TAB
L"%8x" TAB //"ActiveHKL" TAB
L"%hs:%d" TAB //"SourceFile" TAB
L"%s\n", //"Message"
L"%ls\n", //"Message"
sProcessName, //"Process" TAB
pid, //"PID" TAB
tid, //"TID" TAB
shiftState, //"ShiftState" TAB
actualShiftState, // ActualShiftState TAB
tickCount, //"TickCount" TAB
gti.hwndFocus, //"FocusHWND" TAB
activeHKL, //"ActiveHKL" TAB
(unsigned int) pid, //"PID" TAB
(unsigned int) tid, //"TID" TAB
(unsigned int) shiftState, //"ShiftState" TAB
(unsigned int) actualShiftState, // ActualShiftState TAB
(int) tickCount, //"TickCount" TAB
PtrToInt(gti.hwndFocus), //"FocusHWND" TAB
PtrToInt(activeHKL), //"ActiveHKL" TAB
file, line, //"SourceFile" TAB
msg); //"Message"

View file

@ -47,7 +47,7 @@ BOOL GetKeyboardFileName(LPSTR kbname, LPSTR buf, int nbuf)
if(!_td) return FALSE;
if(_td->ForceFileName[0])
{
strncpy_s(buf, nbuf, _td->ForceFileName, nbuf);
strncpy_s(buf, nbuf, _td->ForceFileName, nbuf - 1);
buf[nbuf-1] = 0;
return TRUE;
}
@ -84,7 +84,7 @@ BOOL LoadlpKeyboard(int i)
if(_td->lpActiveKeyboard == &_td->lpKeyboards[i]) _td->lpActiveKeyboard = NULL; // I822 TSF not working
char buf[256];
if(!GetKeyboardFileName(_td->lpKeyboards[i].Name, buf, 256)) return FALSE;
if(!GetKeyboardFileName(_td->lpKeyboards[i].Name, buf, 255)) return FALSE;
if(!LoadKeyboard(buf, &_td->lpKeyboards[i].Keyboard)) return FALSE; // I5136
@ -205,11 +205,14 @@ BOOL LoadKeyboard(LPSTR fileName, LPKEYBOARD *lpKeyboard)
CloseHandle(hFile);
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return FALSE;
if (!_td) {
delete[] buf;
return FALSE;
}
if(*LPDWORD(filebase) != FILEID_COMPILED)
{
delete buf;
delete[] buf;
Err("Invalid file");
return FALSE;
}

View file

@ -246,10 +246,17 @@ void DoCWMF(UINT msg)
void DoChangeWindowMessageFilter()
{
PChangeWindowMessageFilter = (BOOL (WINAPI *)(UINT,DWORD))GetProcAddress(LoadLibrary("user32"), "ChangeWindowMessageFilter");
HMODULE hUser32 = LoadLibrary("user32");
if (!hUser32)
return;
if(!PChangeWindowMessageFilter)
return;
PChangeWindowMessageFilter = (BOOL (WINAPI *)(UINT,DWORD))GetProcAddress(hUser32, "ChangeWindowMessageFilter");
if (!PChangeWindowMessageFilter)
{
FreeLibrary(hUser32);
return;
}
DoCWMF(wm_keyman); // I3594
DoCWMF(wm_keyman_keyevent);
@ -263,6 +270,8 @@ void DoChangeWindowMessageFilter()
DoCWMF(wm_keymanshift);
DoCWMF(wm_keyman_control); // I4714
DoCWMF(wm_keyman_control_internal); // I4714
FreeLibrary(hUser32);
}
BOOL InitThread(HWND hwnd)
@ -591,7 +600,7 @@ extern "C" BOOL _declspec(dllexport) WINAPI Keyman_ForceKeyboard(PCSTR FileName
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return FALSE;
strncpy(_td->ForceFileName, FileName, MAX_PATH);
strncpy(_td->ForceFileName, FileName, MAX_PATH - 1);
_td->ForceFileName[MAX_PATH-1] = 0;
if(_td->lpActiveKeyboard)
@ -767,7 +776,7 @@ BOOL ConvertStringToGuid(WCHAR *buf, GUID *guid) // I3581
}
void LoadBaseLayoutSettings() { // I4552 // I4583
char underlyingLayout[16];
char underlyingLayout[16] = "";
wchar_t baseLayout[MAX_PATH];
DWORD dwUnderlyingLayout = 0;
@ -776,7 +785,7 @@ void LoadBaseLayoutSettings() { // I4552 // I4583
if(reg->OpenKeyReadOnly(REGSZ_KeymanCU)) {
if(reg->ReadString(REGSZ_UnderlyingLayout, underlyingLayout, 15)) {
dwUnderlyingLayout = strtoul(underlyingLayout, NULL, 16); // I4516 // I4581
wsprintf(underlyingLayout, "%08x", dwUnderlyingLayout); // I3759 // I4581
wsprintf(underlyingLayout, "%08x", (unsigned int) dwUnderlyingLayout); // I3759 // I4581
} else {
underlyingLayout[0] = 0;
}
@ -797,7 +806,7 @@ void LoadBaseLayoutSettings() { // I4552 // I4583
if(GetLocaleInfoW(LOWORD(dwUnderlyingLayout), LOCALE_SISO639LANGNAME, langName, _countof(langName)) > 0 &&
GetLocaleInfoW(LOWORD(dwUnderlyingLayout), LOCALE_SISO3166CTRYNAME, countryName, _countof(countryName)) > 0) { // I4588 // I4786
wsprintfW(baseLayoutAlt, L"%s-%s", langName, countryName);
wsprintfW(baseLayoutAlt, L"%ls-%ls", langName, countryName);
Globals::SetBaseKeyboardName(baseLayout, baseLayoutAlt);
} else {
Globals::SetBaseKeyboardName(baseLayout, L"en-US"); // I4786
@ -864,7 +873,7 @@ void RefreshKeyboards(BOOL Initialising)
char oldname[_MAX_FNAME];
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(_td->FInRefreshKeyboards) return;
if(!_td || _td->FInRefreshKeyboards) return;
_td->FInRefreshKeyboards = TRUE;
// Can happen when multiple top-level windows for one process
@ -922,7 +931,7 @@ void RefreshKeyboards(BOOL Initialising)
if(_td->lpKeyboards)
{
memcpy(kp, _td->lpKeyboards, sizeof(INTKEYBOARDINFO)*_td->nKeyboards);
delete _td->lpKeyboards;
delete[] _td->lpKeyboards;
}
_td->nKeyboards = nk + 1;
_td->lpKeyboards = kp;

View file

@ -11,6 +11,7 @@ private:
public:
SharedBufferManager() {
m_pSharedData = NULL;
m_hMMF = OpenFileMapping(FILE_MAP_READ, FALSE, GLOBAL_SHAREDBUFFER_FILE_MAPPING_NAME);
if (!m_hMMF) {
DebugLastError("OpenFileMapping");

View file

@ -38,7 +38,7 @@ void Addin_Release()
if(_td->Addins[i].Uninitialise) (*_td->Addins[i].Uninitialise)();
FreeLibrary(_td->Addins[i].hAddin);
}
delete _td->Addins;
delete[] _td->Addins;
}
_td->Addins = NULL;
_td->nAddins = 0;
@ -56,14 +56,14 @@ void ReadAddins(HKEY hkey)
if(reg->OpenKeyReadOnly(hkey == HKEY_CURRENT_USER ? REGSZ_KeymanAddinsCU : REGSZ_KeymanAddinsLM))
{
int n = _td->nAddins;
char buf[128], buf2[512];
char buf[128];
while(reg->GetValueNames(buf, 128, n))
{
Addin *a = new Addin[n+1];
if(_td->Addins)
{
memcpy(a, _td->Addins, n * sizeof(Addin));
delete _td->Addins;
delete[] _td->Addins;
}
_td->Addins = a;
_td->Addins[n].hAddin = 0;
@ -74,17 +74,9 @@ void ReadAddins(HKEY hkey)
_td->Addins[n].Uninitialise = NULL;
_td->Addins[n].ShouldProcess = NULL;
strcpy(_td->Addins[n].ClassName, buf);
reg->ReadString(buf, buf2, 512);
//char *p = strtok(buf2, ",");
//if(p)
//{
_td->Addins[n].Application[0] = 0;
//strcpy(Addins[n].Application, p);
//p = strtok(NULL, ",");
strcpy(_td->Addins[n].AddinName, buf2); //p);
//SendDebugMessageFormat(GetFocus(), sdmGlobal, 0, "Addins: ReadAddins: App=%s Addin=%s %d", Addins[n].Application, Addins[n].AddinName, Addins[n].hAddin);
n++;
//}
reg->ReadString(buf, _td->Addins[n].AddinName, 260);
_td->Addins[n].Application[0] = 0;
n++;
}
_td->nAddins = n;
}

View file

@ -259,6 +259,9 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM
AITIP::AITIP() {
::AIWin2000Unicode(); // I3574
FIsDebugControlWindow = FALSE;
useLegacy = FALSE;
WM_KEYMANDEBUG_CANDEBUG = RegisterWindowMessage("WM_KEYMANDEBUG_CANDEBUG");
WM_KEYMANDEBUG_GETUNICODESTATUS = RegisterWindowMessage("WM_KEYMANDEBUG_GETUNICODESTATUS");
WM_KEYMANDEBUG_GETCONTEXT = RegisterWindowMessage("WM_KEYMANDEBUG_GETCONTEXT");
@ -548,7 +551,7 @@ BOOL AITIP::PostKeys() {
SendDebugMessageFormat(0, sdmAIDefault, 0, "AITIP::PostKeys: no output");
}
delete OutBuf; // I4272
delete[] OutBuf; // I4272
QueueSize = 0;
return TRUE;
@ -643,7 +646,7 @@ void FillStoreOffsets(AIDEBUGINFO *di)
if(n == MAXSTOREOFFSETS*2) break;
}
if(n < MAXSTOREOFFSETS*2)
if(n < MAXSTOREOFFSETS*2 - 1)
for(p = di->Rule->dpOutput; *p; p = incxstr(p))
{
if(*p == UC_SENTINEL && *(p+1) == CODE_INDEX)

View file

@ -303,7 +303,7 @@ BOOL AIWin2000Unicode::PostKeys()
SendDebugMessageFormat(0, sdmAIDefault, 0, "App::PostKeys: sending input finished");
delete pInputs;
delete[] pInputs;
return TRUE;
}

View file

@ -160,6 +160,7 @@ BOOL AppContext::CharIsSurrogatePair()
AppActionQueue::AppActionQueue()
{
memset(Queue, 0, sizeof(APPACTIONQUEUEITEM) * MAXACTIONQUEUE);
ResetQueue();
}
@ -192,4 +193,5 @@ BOOL AppActionQueue::QueueAction(int ItemType, DWORD dwData)
AppIntegration::AppIntegration()
{
hwnd = NULL;
FShiftFlags = 0;
}

View file

@ -43,7 +43,7 @@ static LPIMDLL AddIMDLL(LPINTKEYBOARDINFO lpkbi, LPSTR kbdpath, LPSTR dllfilenam
char drive[_MAX_DRIVE], dir[_MAX_DIR], fullname[_MAX_PATH], newdllname[_MAX_FNAME];
strcpy(fullname, kbdpath);
strcpy_s(fullname, _countof(fullname), kbdpath);
_splitpath_s(fullname, drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0); // I3547
#ifdef _WIN64
@ -160,7 +160,7 @@ BOOL LoadDLLs(LPINTKEYBOARDINFO lpkbi)
if(!q || !r)
{
s->dwSystemID = TSS_CALLDEFINITION_LOADFAILED;
delete p;
delete[] p;
continue;
}
@ -168,7 +168,7 @@ BOOL LoadDLLs(LPINTKEYBOARDINFO lpkbi)
if(imd && AddIMDLLHook(imd, r, i, &s->dpString)) s->dwSystemID = TSS_CALLDEFINITION;
else s->dwSystemID = TSS_CALLDEFINITION_LOADFAILED;
delete p;
delete[] p;
}
}
@ -225,7 +225,7 @@ void CallDLL(LPINTKEYBOARDINFO lpkbi, DWORD storenum)
{
//SendDebugMessageFormat(0, sdmKeyboard, 0, "CallDll: Enter");
if(storenum < 0 || storenum >= lpkbi->Keyboard->cxStoreArray) return;
if(storenum >= lpkbi->Keyboard->cxStoreArray) return;
LPSTORE s = &lpkbi->Keyboard->dpStoreArray[storenum];
if(s->dwSystemID != TSS_CALLDEFINITION) return;

View file

@ -201,35 +201,35 @@ void DebugMessage(LPMSG msg, WPARAM wParam) // I2908
char ds[256];
if(msg->message == wm_keymankeydown)
wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd,
Debug_VirtualKey((WORD) msg->wParam), msg->lParam, wParam, msg->time);
wsprintf(ds, "DebugMessage(%x, wm_keymankeydown: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
else if(msg->message == wm_keymankeyup)
wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd,
Debug_VirtualKey((WORD) msg->wParam), msg->lParam, wParam, msg->time);
wsprintf(ds, "DebugMessage(%x, wm_keymankeyup: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
Debug_VirtualKey((WORD) msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
else if (msg->message == wm_keyman_keyevent)
wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", msg->hwnd,
Debug_VirtualKey((WORD)msg->wParam), msg->lParam, wParam, msg->time);
wsprintf(ds, "DebugMessage(%x, wm_keyman_keyevent: %s lParam: %X) [message flags: %x time: %d]", PtrToInt(msg->hwnd),
Debug_VirtualKey((WORD)msg->wParam), (unsigned int) msg->lParam, wParam, (int) msg->time);
else if(msg->message == WM_KEYDOWN || msg->message == WM_KEYUP || msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP)
wsprintf(ds, "DebugMessage(%x, %s, wParam: %s, lParam: %X) [message flags: %x time: %d extra: %x]",
msg->hwnd,
PtrToInt(msg->hwnd),
msgnames[msg->message-WM_KEYDOWN],
Debug_VirtualKey((WORD) msg->wParam),
msg->lParam,
(unsigned int) msg->lParam,
wParam,
msg->time,
GetMessageExtraInfo());
(int) msg->time,
(unsigned int) GetMessageExtraInfo());
else if(msg->message >= WM_KEYDOWN && msg->message <= WM_UNICHAR)
wsprintf(ds, "DebugMessage(%x, %s, wParam: '%c' (U+%04X), lParam: %X) [message flags: %x time: %d extra: %x]",
msg->hwnd,
PtrToInt(msg->hwnd),
msgnames[msg->message-WM_KEYDOWN],
msg->wParam,
msg->wParam,
msg->lParam,
(unsigned int) msg->lParam,
wParam,
msg->time,
GetMessageExtraInfo());
(int) msg->time,
(unsigned int) GetMessageExtraInfo());
else
wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", msg->hwnd, msg->message, msg->wParam, msg->lParam, wParam, msg->time);
wsprintf(ds, "%x: %d: wParam: %d, lParam: %X [message flags: %x time: %d]", PtrToInt(msg->hwnd), msg->message, msg->wParam, (unsigned int) msg->lParam, wParam, (int) msg->time);
SendDebugMessage(msg->hwnd, sdmMessage, 0, ds);
}

View file

@ -123,6 +123,9 @@ BOOL OpenTSF(PKEYMAN64THREADDATA _td)
BOOL CloseTSF()
{
PKEYMAN64THREADDATA _td = ThreadGlobals();
if (!_td) {
return FALSE;
}
/*if(_td->dwSinkCookie != (DWORD)-1 && _td->pSource) {
_td->pSource->UnadviseSink(_td->dwSinkCookie);

View file

@ -67,18 +67,21 @@ void do_keybd_event(LPINPUT pInputs, int *n, BYTE vk, BYTE scan, DWORD flags, UL
switch(vk) {
case VK_RCONTROL:
flags |= KEYEVENTF_EXTENDEDKEY;
/*fallthrough*/
case VK_LCONTROL:
vk = VK_CONTROL;
break;
case VK_RMENU:
flags |= KEYEVENTF_EXTENDEDKEY;
/*fallthrough*/
case VK_LMENU:
vk = VK_MENU;
break;
case VK_RSHIFT:
scan = SCANCODE_RSHIFT; // from kbd.h
/*fallthrough*/
case VK_LSHIFT:
vk = VK_SHIFT;
break;

View file

@ -102,7 +102,7 @@ void ResetKeyboardOption(LPINTKEYBOARDINFO kp, int nStoreToReset)
{
if(r.ValueExists(kp->Keyboard->dpStoreArray[nStoreToReset].dpName))
{
WCHAR val[255];
WCHAR val[256];
if(!r.ReadString(kp->Keyboard->dpStoreArray[nStoreToReset].dpName, val, sizeof(val) / sizeof(val[0]))) return;
if(!val[0]) return;
val[255] = 0;

View file

@ -360,8 +360,8 @@ void ProcessWMKeyman(HWND hwnd, WPARAM wParam, LPARAM lParam)
}
SelectApplicationIntegration();
if(!_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
_td->state.windowunicode = _td->app->IsUnicode();
if(_td->app && !_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
_td->state.windowunicode = !_td->app || _td->app->IsUnicode();
if(IsFocusedThread())
{
@ -483,4 +483,4 @@ BOOL IsFocusedThread()
}
return gti.hwndFocus == GetFocus();
//return GetCurrentThreadId() == GetWindowThreadProcessId(GetForegroundWindow(), NULL);
}
}

View file

@ -640,14 +640,14 @@ BOOL IsMatchingPlatform(LPSTORE s) // I3432
if(!IsMatchingPlatformString(platform))
{
s->dwSystemID = TSS_PLATFORM_NOMATCH;
delete t;
delete[] t;
return FALSE;
}
platform = wcstok_s(NULL, L" ", &context);
}
s->dwSystemID = TSS_PLATFORM_MATCH;
delete t;
delete[] t;
return TRUE;
}

View file

@ -104,8 +104,8 @@ BOOL SelectKeyboard(DWORD KeymanID)
ResetCapsLock();
SelectApplicationIntegration(); // I4287
if(!_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
_td->state.windowunicode = _td->app->IsUnicode();
if(_td->app && !_td->app->IsWindowHandled(hwnd)) _td->app->HandleWindow(hwnd);
_td->state.windowunicode = !_td->app || _td->app->IsUnicode();
ActivateDLLs(_td->lpActiveKeyboard);
@ -180,14 +180,14 @@ void SelectKeyboardHKL(PKEYMAN64THREADDATA _td, DWORD hkl, BOOL foreground) {
}
void PrepareLanguageSwitchString(UINT langid, HKL hkl, char *str) {
wsprintf(str, "%d|%d|%d", GetCurrentThreadId(), langid, hkl); // I4285
wsprintf(str, "%d|%d|%d", (int) GetCurrentThreadId(), langid, PtrToInt(hkl)); // I4285
}
void PrepareLanguageSwitchString(UINT langid, GUID clsid, GUID guidProfile, char *str) {
WCHAR clsidstr[40], profilestr[40];
StringFromGUID2(clsid, clsidstr, _countof(clsidstr));
StringFromGUID2(guidProfile, profilestr, _countof(profilestr));
wsprintf(str, "%d|%d|%ws|%ws", GetCurrentThreadId(), langid, clsidstr, profilestr); // I4285
wsprintf(str, "%d|%d|%ls|%ls", (int) GetCurrentThreadId(), langid, clsidstr, profilestr); // I4285
}
void ReportActiveKeyboard(PKEYMAN64THREADDATA _td, WORD wCommand) { // I3933 // I3949

View file

@ -61,6 +61,18 @@ private:
public:
SerialKeyEventServer() {
m_idThread = 0;
m_hThread = NULL;
m_hThreadExitEvent = NULL;
memset(m_ModifierKeyboardState, 0, 256);
m_hKeyEvent = NULL;
m_hKeyMutex = NULL;
m_hMMF = NULL;
m_hwnd = NULL;
m_nInputs = 0;
m_pInputs = NULL;
m_pSharedData = NULL;
// We create the file mapping and global data on the main thread but release it on the
// local thread. This ensures that these objects are available for other processes to
// open even if we haven't completed startup of the local thread.
@ -102,6 +114,10 @@ public:
DebugLastError("CloseHandle(m_hThreadExitEvent)");
}
}
// Normally, this is cleaned up by thread termination, but this
// handles error conditions better
CloseSharedData();
}
virtual HWND GetWindow() const {
@ -170,21 +186,25 @@ private:
DebugLastError("CloseHandle(m_hKeyMutex)");
bRet = FALSE;
}
m_hKeyMutex = NULL;
if (m_hKeyEvent != NULL && !CloseHandle(m_hKeyEvent)) {
DebugLastError("CloseHandle(m_hKeyEvent)");
bRet = FALSE;
}
m_hKeyEvent = NULL;
if (m_pSharedData != NULL && !UnmapViewOfFile((LPCVOID)m_pSharedData)) {
DebugLastError("CloseHandle(m_pSharedData)");
bRet = FALSE;
}
m_pSharedData = NULL;
if (m_hMMF != NULL && !CloseHandle(m_hMMF)) {
DebugLastError("CloseHandle(m_hMMF)");
bRet = FALSE;
}
m_hMMF = NULL;
return bRet;
}
@ -268,7 +288,8 @@ private:
}
if (m_pInputs != NULL) {
delete m_pInputs;
delete[] m_pInputs;
m_pInputs = NULL;
}
}

View file

@ -52,6 +52,8 @@ void GetWindowsVersion(char *buf)
if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1 )
pos = "Microsoft Windows 7";
// TODO: Update this for Win8, Win10, etc
// Test for product type.
if ( osvi.wProductType == VER_NT_WORKSTATION )
@ -77,16 +79,16 @@ void GetWindowsVersion(char *buf)
if ( osvi.dwMajorVersion <= 4 )
{
wsprintf (verinfo, "version %d.%d %s (Build %d)",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
(int) osvi.dwMajorVersion,
(int) osvi.dwMinorVersion,
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
(int)(osvi.dwBuildNumber & 0xFFFF));
}
else
{
wsprintf (verinfo, "version %s (Build %d)",
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
(int)(osvi.dwBuildNumber & 0xFFFF));
}
break;
@ -121,6 +123,6 @@ void GetWindowsVersion(char *buf)
break;
}
wsprintf(buf, "Platform %s OS %s%s%s %s", pplatform, pos, pextra ? " " : "", pextra, verinfo);
wsprintf(buf, "Platform %s OS %s %s %s", pplatform, pos, *pextra ? " " : "", pextra, verinfo);
}
#pragma warning(default: 4996)

View file

@ -236,6 +236,23 @@ begin
LangID := LocaleNameToLCID(PWideChar(Locale), 0);
if (PRIMARYLANGID(LangID) = 0) and (
(SUBLANGID(LangID) < 8) or
(SUBLANGID(LangID) > 11)
) then
begin
// LocaleNameToLCID can return a language code that is 'transient' but
// outside of the supported range of $2000, $2400, $2800, $2C00. For
// example, we have seen values of $3000, $3400, $3800.
// Set-WinUserLanguageList refuses to play ball with these values, so we
// reject them as invalid.
//
// This may be a bug in Windows? TODO: Investigate further and report to
// Microsoft
Exit(False);
end;
case LangID of
LOCALE_CUSTOM_DEFAULT,
LOCALE_CUSTOM_UNSPECIFIED,

View file

@ -65,19 +65,19 @@ void InitDebugging() {
VS_FIXEDFILEINFO *ffi;
DWORD sz;
UINT ffilen;
char *buf = new char[1024], fname[260];
char fname[260];
GetModuleFileName(GetModuleHandle("kmtip.dll"), fname, 260);
sz = GetFileVersionInfoSize(fname, 0);
if (sz > 0) {
buf = new char[sz];
char *buf = new char[sz];
GetFileVersionInfo(fname, 0, sz, buf);
VerQueryValue(buf, "\\", (void **)&ffi, &ffilen);
SendDebugMessageFormat(L"kmtip version: %d.%d.%d.%d",
HIWORD(ffi->dwProductVersionMS), LOWORD(ffi->dwProductVersionMS),
HIWORD(ffi->dwProductVersionLS), LOWORD(ffi->dwProductVersionLS));
delete buf; // I2157
delete[] buf; // I2157
}
else {
SendDebugMessage(L"kmtip version: damaged");

View file

@ -1,4 +1,4 @@
/*
/*
Name: inserttext
Copyright: Copyright (C) SIL International.
Documentation:
@ -268,7 +268,7 @@ BOOL GetLeftOfSelection(TfEditCookie ec, ITfContext *pContext, WCHAR *buf, LONG
if(ShouldDebug()) {
char *p = debugstr(buf);
Log(L"GetLeftOfSelection(%d) = %hs [%d fetched]", n, p, cFetched);
delete p;
delete[] p;
}
#ifdef DEBUG_PSEUDO // I3607
DePseudofy(buf); // I3564

View file

@ -56,6 +56,8 @@ public:
_fUpdate = fUpdate;
_fPreserved = fPreserved; // I3588
_dwDeepIntegration = dwDeepIntegration; // I4375
_hr = S_FALSE;
_ec = 0;
}
// ITfEditSession
@ -245,7 +247,7 @@ HRESULT WINAPI CKeymanEditSession::KeymanProcessOutput(int n, WCHAR *buf, int nb
if (ShouldDebug()) {
char *p = debugstr(buf);
SendDebugMessageFormat(L"KeymanProcessOutput: fUpdate = %d, deleting %d, inserting %d '%hs'", _fUpdate, n, nbuf, p); // I4262
delete p;
delete[] p;
}
if (_fUpdate) {

View file

@ -79,6 +79,14 @@ CKMTipTextService::CKMTipTextService()
// I3582
_dwThreadMgrEventSinkCookie = TF_INVALID_COOKIE;
memset(&guidActiveProfile, 0, sizeof(GUID));
_keystrokeSinkInitialized = FALSE;
_hKeyman = NULL;
_dwActiveLanguageProfileNotifySinkCookie = 0;
_PreservedKeys = NULL;
_cPreservedKeyCount = 0;
_dwDeepIntegration = 0;
_cRef = 1;
ThreadThis = this;
}
@ -283,4 +291,4 @@ STDAPI CKMTipTextService::Deactivate()
_tfClientId = TF_CLIENTID_NULL;
return S_OK;
}
}

View file

@ -72,16 +72,12 @@ BOOL CKMTipTextService::RegisterProfiles()
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles, (void**)&pInputProcessProfiles);
if (hr != S_OK)
if (hr != S_OK || pInputProcessProfiles == NULL)
return FALSE;
hr = pInputProcessProfiles->Register(c_clsidKMTipTextService);
if (hr != S_OK)
goto Exit;
Exit:
if(pInputProcessProfiles != NULL) // I2794
pInputProcessProfiles->Release();
pInputProcessProfiles->Release();
return (hr == S_OK);
#endif

View file

@ -462,7 +462,7 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector<DeadkeyMapping> *FDeadk
Loader loader;
WCHAR inputHKL[12];
wsprintf(inputHKL, L"%08.8x", wcstol(kbid, NULL, 16));
wsprintf(inputHKL, L"%08.8x", (unsigned int) wcstol(kbid, NULL, 16));
int cKeyboards = GetKeyboardLayoutList(0, NULL);
HKL *rghkl = new HKL[cKeyboards];
@ -470,6 +470,7 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector<DeadkeyMapping> *FDeadk
HKL hkl = LoadKeyboardLayout(inputHKL, KLF_NOTELLSHELL);
if(hkl == NULL) {
puts("Sorry, that keyboard does not seem to be valid.");
delete[] rghkl;
return false;
}
@ -595,6 +596,8 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector<DeadkeyMapping> *FDeadk
UnloadKeyboardLayout(hkl);
}
delete[] rghkl;
//-------------------------------------------------------------
// Now that we've collected the key data, we need to
// translate it to kmx and append to the existing keyboard

View file

@ -40,26 +40,31 @@ BOOL LoadKeyboard(LPWSTR fileName, LPKEYBOARD *lpKeyboard) {
filebase = buf;
ReadFile(hFile, filebase, sz, &sz, NULL);
if(!ReadFile(hFile, filebase, sz, &sz, NULL)) {
Err(L"errReadFile");
CloseHandle(hFile);
delete[] buf;
return FALSE;
}
CloseHandle(hFile);
if(!VerifyKeyboard(filebase, sz)) {
Err(L"errVerifyKeyboard");
delete buf;
delete[] buf;
return FALSE;
}
kbp = FixupKeyboard(buf, filebase, sz);
if(!kbp) {
Err(L"errFixupKeyboard");
delete buf;
delete[] buf;
return FALSE;
}
if(kbp->dwIdentifier != FILEID_COMPILED) {
Err(L"errNotFileID");
delete buf;
return FALSE;
if(kbp->dwIdentifier != FILEID_COMPILED) {
Err(L"errNotFileID");
delete[] buf;
return FALSE;
}
*lpKeyboard = kbp;
@ -93,7 +98,7 @@ LPKEYBOARD FixupKeyboard(PBYTE bufp, PBYTE base, DWORD dwFileSize) {
}
for(gp = kbp->dpGroupArray, cgp = (PCOMP_GROUP) gp, i = 0; i < kbp->cxGroupArray; i++, gp++, cgp++) {
gp->dpName = StringOffset(base, cgp->dpName);
gp->dpName = StringOffset(base, cgp->dpName);
gp->dpKeyArray = (LPKEY) (base + cgp->dpKeyArray);
if(cgp->dpMatch != NULL) gp->dpMatch = (PWSTR) (base + cgp->dpMatch);
if(cgp->dpNoMatch != NULL) gp->dpNoMatch = (PWSTR) (base + cgp->dpNoMatch);
@ -124,12 +129,12 @@ BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz) {
PCOMP_KEYBOARD ckbp = (PCOMP_KEYBOARD) filebase;
PCOMP_STORE csp;
/* Check file version */
/* Check file version */
if(ckbp->dwFileVersion < VERSION_MIN ||
ckbp->dwFileVersion > VERSION_MAX) {
/* Old or new version -- identify the desired program version */
if(VerifyChecksum(filebase, sz)) {
if(ckbp->dwFileVersion < VERSION_MIN ||
ckbp->dwFileVersion > VERSION_MAX) {
/* Old or new version -- identify the desired program version */
if(VerifyChecksum(filebase, sz)) {
for(csp = (PCOMP_STORE)(filebase + ckbp->dpStoreArray), i = 0; i < ckbp->cxStoreArray; i++, csp++) {
if(csp->dwSystemID == TSS_COMPILEDVERSION) {
wchar_t buf2[256];
@ -144,12 +149,12 @@ BOOL VerifyKeyboard(LPBYTE filebase, DWORD sz) {
}
}
Err(L"errWrongFileVersion");
return FALSE;
return FALSE;
}
if(!VerifyChecksum(filebase, sz)) {
Err(L"errBadChecksum");
return FALSE;
if(!VerifyChecksum(filebase, sz)) {
Err(L"errBadChecksum");
return FALSE;
}
return TRUE;

View file

@ -45,11 +45,11 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
// Calculate how much memory to allocate
size = sizeof(COMP_KEYBOARD) +
fk->cxGroupArray * sizeof(COMP_GROUP) +
size = sizeof(COMP_KEYBOARD) +
fk->cxGroupArray * sizeof(COMP_GROUP) +
fk->cxStoreArray * sizeof(COMP_STORE) +
/*wcslen(fk->szName)*2 + 2 +
wcslen(fk->szCopyright)*2 + 2 +
/*wcslen(fk->szName)*2 + 2 +
wcslen(fk->szCopyright)*2 + 2 +
wcslen(fk->szLanguageName)*2 + 2 +
wcslen(fk->szMessage)*2 + 2 +*/
fk->dwBitmapSize;
@ -62,7 +62,7 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
size += wcslen(fkp->dpOutput)*2 + 2;
size += wcslen(fkp->dpContext)*2 + 2;
}
if( fgp->dpMatch ) size += wcslen(fgp->dpMatch)*2 + 2;
if( fgp->dpNoMatch ) size += wcslen(fgp->dpNoMatch)*2 + 2;
}
@ -91,7 +91,7 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
ck->StartGroup[0] = fk->StartGroup[0];
ck->StartGroup[1] = fk->StartGroup[1];
ck->dwHotKey = fk->dwHotKey;
ck->dwFlags = fk->dwFlags;
offset = sizeof(COMP_KEYBOARD);
@ -168,12 +168,12 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
offset += gp->cxKeyArray * sizeof(COMP_KEY);
for(j = 0; j < gp->cxKeyArray; j++, kp++, fkp++) {
kp->Key = fkp->Key;
kp->Line = fkp->Line;
kp->Line = fkp->Line;
kp->ShiftFlags = fkp->ShiftFlags;
kp->dpOutput = offset;
wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpOutput); // I3481 // I3641
offset += wcslen(fkp->dpOutput)*2 + 2;
kp->dpContext = offset;
wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpContext); // I3481 // I3641
@ -191,15 +191,23 @@ DWORD WriteCompiledKeyboard(LPKEYBOARD fk, HANDLE hOutfile, BOOL FSaveDebug)
ck->dpBitmapOffset = 0;
}
if(offset != size) return CERR_SomewhereIGotItWrong;
if(offset != size)
{
delete[] buf;
return CERR_SomewhereIGotItWrong;
}
SetChecksum(buf, &ck->dwCheckSum, size);
WriteFile(hOutfile, buf, size, &offset, NULL);
if(offset != size) return CERR_UnableToWriteFully;
if(offset != size)
{
delete[] buf;
return CERR_UnableToWriteFully;
}
delete buf;
delete[] buf;
return CERR_None;
}

View file

@ -261,11 +261,11 @@ const WCHAR cp1252[256] = {
void InplaceUnicode(PWSTR p) {
while(p && *p) {
if(*p != UC_SENTINEL) {
if(*p >= 0 && *p <= 0xFF) {
if(*p <= 0xFF) {
*p = cp1252[*p];
}
}
p = incxstr(p);
}
}
@ -276,7 +276,7 @@ BOOL ConvertKeyboardToUnicode(LPKEYBOARD kbd) {
LPKEY kp;
DWORD i, j;
if(kbd->StartGroup[BEGIN_UNICODE] >= 0 && kbd->StartGroup[BEGIN_UNICODE] < kbd->cxGroupArray) {
if(kbd->StartGroup[BEGIN_UNICODE] < kbd->cxGroupArray) {
// Keyboard is already Unicode
return TRUE;
}

View file

@ -1,18 +1,18 @@
/*
Name: mcompile
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 24 Apr 2014
Modified Date: 8 Apr 2015
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 24 Apr 2014 - mcdurdin - I4174 - V9 - mcompile logs should be stored in diag folder
16 Jun 2014 - mcdurdin - I4273 - V9.0 - Convert keyboards to Unicode before installing
23 Jun 2014 - mcdurdin - I4279 - V9.0 - mcompile fails to start when converting keyboard to Unicode
@ -82,7 +82,7 @@ int run(int argc, wchar_t * argv[])
}
//DeleteReallocatedPointers(kmxfile); :TODO
delete kmxfile;
delete[] kmxfile;
return 0; // I4279
}
@ -92,11 +92,11 @@ int run(int argc, wchar_t * argv[])
wchar_t *infile = argv[n], *indll = argv[n+1], *kbid = argv[n+2], *outfile = argv[n+3];
wprintf(L"mcompile%s \"%s\" \"%s\" \"%s\" \"%s\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174
wprintf(L"mcompile%ls \"%ls\" \"%ls\" \"%ls\" \"%ls\"\n", bDeadkeyConversion ? L" -d":L"", infile, indll, kbid, outfile); // I4174
// 1. Load the keyman keyboard file
// 2. For each key on the system layout, determine its output character and perform a
// 2. For each key on the system layout, determine its output character and perform a
// 1-1 replacement on the keyman keyboard of that character with the base VK + shift
// state. This fixup will transform the char to a vk, which will avoid any issues
// with the key.
@ -107,8 +107,8 @@ int run(int argc, wchar_t * argv[])
// rule for that deadkey, e.g. [K_LBRKT] > dk(c101)
//
// Next, update each rule that references the output from that deadkey to add an extra
// context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'.
// This will require a memory layout change for the .kmx file, plus fixups on the
// context deadkey at the end of the context match, e.g. 'a' dk(c101) + [K_SPACE] > 'b'.
// This will require a memory layout change for the .kmx file, plus fixups on the
// context+output index offsets
//
// --> virtual character keys
@ -117,7 +117,7 @@ int run(int argc, wchar_t * argv[])
// switch the shift state from the VIRTUALCHARKEY to VIRTUALKEY, without changing any
// other properties of the key.
//
// 3. Write the new keyman keyboard file
if(!LoadNewLibrary(indll)) {
@ -167,7 +167,7 @@ const UINT VKShiftState[] = {0, K_SHIFTFLAG, LCTRLFLAG|RALTFLAG, K_SHIFTFLAG|LCT
//
// TranslateKey
//
// For each key rule on the keyboard, remap its key to the
// For each key rule on the keyboard, remap its key to the
// correct shift state and key. Adjust the LCTRL+RALT -> RALT if necessary
//
void TranslateKey(LPKEY key, WORD vk, UINT shift, WCHAR ch) {
@ -391,7 +391,7 @@ void ConvertDeadkey(LPKEYBOARD kbd, WORD vk, UINT shift, WCHAR deadkey) {
GetDeadkeys(deadkey, pdk = deadkeys); // returns array of [usvk, ch_out] pairs
while(*pdk) {
// Look up the ch
// Look up the ch
UINT vkUnderlying = VKUnderlyingLayoutToVKUS(*pdk);
TranslateDeadkeyKeyboard(kbd, dkid, vkUnderlying, *(pdk+1), *(pdk+2));
pdk+=3;
@ -435,7 +435,7 @@ BOOL DoConvert(LPKEYBOARD kbd, LPWSTR kbid, BOOL bDeadkeyConversion) { // I455
// Go through each possible key on the keyboard
for(int i = 0; VKMap[i]; i++) { // I4651
UINT vkUnderlying = VKUSToVKUnderlyingLayout(VKMap[i]);
WCHAR ch = CharFromVK(vkUnderlying, VKShiftState[j], &DeadKey);
//LogError("--- VK_%d -> VK_%d [%c] dk=%d", VKMap[i], vkUnderlying, ch == 0 ? 32 : ch, DeadKey);

View file

@ -17,8 +17,6 @@ uses
Keyman.System.Standards.LangTagsRegistry,
System.SysUtils;
// TODO: Make this a COM API function so we aren't shipping 3+MB of standards data multiple times
///
///<summary>Find a language code with appropriate script and region subtags</summary>
///<remarks>

View file

@ -50,7 +50,7 @@ int keyman_sentry_init(bool is_keyman_developer, const char *logger) {
sentry_options_set_release(options, "release-" KEYMAN_VersionWithTag); // matches git tag
sentry_options_set_environment(options, KEYMAN_Environment); // stable, beta, alpha, test, local
// We don't currently need to set this, because it will be same path
// as all our c++ executables.
//sentry_options_set_handler_path(options, "path/to/crashpad_handler");
@ -59,7 +59,7 @@ int keyman_sentry_init(bool is_keyman_developer, const char *logger) {
if (RegOpenKeyExA(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey) == ERROR_SUCCESS) {
DWORD dwType, dwValue, dwValueSize = 4;
g_report_exceptions =
g_report_exceptions =
RegQueryValueExA(hkey, REGSZ_AutomaticallyReportErrors, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize) != ERROR_SUCCESS || dwType != REG_DWORD || dwValue != 0;
dwValueSize = 4;
@ -133,7 +133,7 @@ void keyman_sentry_report_exception(DWORD ExceptionCode, PVOID ExceptionAddress)
const int FRAMES_TO_SKIP = 0;
char message[64];
wsprintfA(message, "Exception %x at %p", ExceptionCode, ExceptionAddress);
wsprintfA(message, "Exception %x at %p", (unsigned int) ExceptionCode, ExceptionAddress);
if (g_report_exceptions) {
event = sentry_value_new_event();