diff --git a/HISTORY.md b/HISTORY.md index 7121c8f3d2..e70f220d45 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -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) diff --git a/VERSION.md b/VERSION.md index d6a5d3932e..de31f8e7c7 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -14.0.153 \ No newline at end of file +14.0.155 \ No newline at end of file diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java index 3856db6ee4..78accf09f7 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KMPBrowserActivity.java @@ -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); diff --git a/android/KMAPro/kMAPro/src/main/res/values/strings.xml b/android/KMAPro/kMAPro/src/main/res/values/strings.xml index 46b4985070..52e2a3dc8c 100644 --- a/android/KMAPro/kMAPro/src/main/res/values/strings.xml +++ b/android/KMAPro/kMAPro/src/main/res/values/strings.xml @@ -112,6 +112,8 @@ (from keyboard package) + + Switching to another keyboard Select Keyboard Package diff --git a/common/core/web/input-processor/package-lock.json b/common/core/web/input-processor/package-lock.json index 5c8c05e105..c65405e442 100644 --- a/common/core/web/input-processor/package-lock.json +++ b/common/core/web/input-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/input-processor/package.json b/common/core/web/input-processor/package.json index 10b29b72ef..accb9cd943 100644 --- a/common/core/web/input-processor/package.json +++ b/common/core/web/input-processor/package.json @@ -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" diff --git a/common/core/web/keyboard-processor/package-lock.json b/common/core/web/keyboard-processor/package-lock.json index 03745147ca..e23e24293b 100644 --- a/common/core/web/keyboard-processor/package-lock.json +++ b/common/core/web/keyboard-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/keyboard-processor/package.json b/common/core/web/keyboard-processor/package.json index 61c42b05bf..b3ba09b60e 100644 --- a/common/core/web/keyboard-processor/package.json +++ b/common/core/web/keyboard-processor/package.json @@ -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" } diff --git a/common/core/web/tools/recorder/package-lock.json b/common/core/web/tools/recorder/package-lock.json index 37e75af20c..a07d7933a6 100644 --- a/common/core/web/tools/recorder/package-lock.json +++ b/common/core/web/tools/recorder/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/recorder/package.json b/common/core/web/tools/recorder/package.json index 4f8f9bb2bd..b74140c295 100644 --- a/common/core/web/tools/recorder/package.json +++ b/common/core/web/tools/recorder/package.json @@ -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" diff --git a/common/core/web/tools/sentry-manager/package-lock.json b/common/core/web/tools/sentry-manager/package-lock.json index 49542541f2..bf7d4a2e74 100644 --- a/common/core/web/tools/sentry-manager/package-lock.json +++ b/common/core/web/tools/sentry-manager/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-sentry-manager", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/sentry-manager/package.json b/common/core/web/tools/sentry-manager/package.json index 5b2798e638..b8dd31e07f 100644 --- a/common/core/web/tools/sentry-manager/package.json +++ b/common/core/web/tools/sentry-manager/package.json @@ -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" } } diff --git a/common/core/web/utils/package-lock.json b/common/core/web/utils/package-lock.json index 462df15f36..f7584f41e4 100644 --- a/common/core/web/utils/package-lock.json +++ b/common/core/web/utils/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/utils/package.json b/common/core/web/utils/package.json index b3d8c6b118..93a60ab77d 100644 --- a/common/core/web/utils/package.json +++ b/common/core/web/utils/package.json @@ -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" } diff --git a/common/models/templates/package-lock.json b/common/models/templates/package-lock.json index 879d5ce7c3..3bfb56c524 100644 --- a/common/models/templates/package-lock.json +++ b/common/models/templates/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-templates", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/templates/package.json b/common/models/templates/package.json index 587a84de63..fedfd43d56 100644 --- a/common/models/templates/package.json +++ b/common/models/templates/package.json @@ -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" } } diff --git a/common/models/templates/src/common.ts b/common/models/templates/src/common.ts index fe3b285c7c..73d360a2e7 100644 --- a/common/models/templates/src/common.ts +++ b/common/models/templates/src/common.ts @@ -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; } } diff --git a/common/models/templates/src/index.ts b/common/models/templates/src/index.ts index 5d63fe73a5..a20b43f602 100644 --- a/common/models/templates/src/index.ts +++ b/common/models/templates/src/index.ts @@ -1,4 +1,5 @@ /// +/// // Add all namespaces defined here to the global scope: if (typeof module != 'undefined' && typeof module.exports != 'undefined') { diff --git a/common/models/templates/src/quote-behavior.ts b/common/models/templates/src/quote-behavior.ts new file mode 100644 index 0000000000..d71dd688dc --- /dev/null +++ b/common/models/templates/src/quote-behavior.ts @@ -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!"; + } + } + } +} \ No newline at end of file diff --git a/common/models/templates/test/test-common.js b/common/models/templates/test/test-common.js new file mode 100644 index 0000000000..61892ad985 --- /dev/null +++ b/common/models/templates/test/test-common.js @@ -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); + }); + }); +}); diff --git a/common/models/templates/test/test-quote-behavior.js b/common/models/templates/test/test-quote-behavior.js new file mode 100644 index 0000000000..339cf0af9d --- /dev/null +++ b/common/models/templates/test/test-quote-behavior.js @@ -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); + }); + }); + }); +}); \ No newline at end of file diff --git a/common/models/types/package-lock.json b/common/models/types/package-lock.json index 2b45bfec80..389ea4b2d3 100644 --- a/common/models/types/package-lock.json +++ b/common/models/types/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-types", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/types/package.json b/common/models/types/package.json index 81b7ac3d90..ebb4b761d7 100644 --- a/common/models/types/package.json +++ b/common/models/types/package.json @@ -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": { diff --git a/common/models/wordbreakers/package-lock.json b/common/models/wordbreakers/package-lock.json index 4d1865bf27..9239d08f04 100644 --- a/common/models/wordbreakers/package-lock.json +++ b/common/models/wordbreakers/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/models-wordbreakers", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/models/wordbreakers/package.json b/common/models/wordbreakers/package.json index 2436c68eed..59492a9516 100644 --- a/common/models/wordbreakers/package.json +++ b/common/models/wordbreakers/package.json @@ -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", diff --git a/common/predictive-text/package-lock.json b/common/predictive-text/package-lock.json index fd9bd8d7e9..830efb9885 100644 --- a/common/predictive-text/package-lock.json +++ b/common/predictive-text/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/predictive-text/package.json b/common/predictive-text/package.json index 8ab942fc5a..bf1eaec4cc 100644 --- a/common/predictive-text/package.json +++ b/common/predictive-text/package.json @@ -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" diff --git a/common/predictive-text/unit_tests/headless/worker-model-compositor.js b/common/predictive-text/unit_tests/headless/worker-model-compositor.js index bdd60699ca..1ba4ba0497 100644 --- a/common/predictive-text/unit_tests/headless/worker-model-compositor.js +++ b/common/predictive-text/unit_tests/headless/worker-model-compositor.js @@ -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: + }); + }); + }); }); diff --git a/common/predictive-text/worker/model-compositor.ts b/common/predictive-text/worker/model-compositor.ts index 24674bd268..9be2b57fe4 100644 --- a/common/predictive-text/worker/model-compositor.ts +++ b/common/predictive-text/worker/model-compositor.ts @@ -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 - } + }; } /** diff --git a/developer/js/package-lock.json b/developer/js/package-lock.json index b305b08c4e..84c1f97273 100644 --- a/developer/js/package-lock.json +++ b/developer/js/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-compiler", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/developer/js/package.json b/developer/js/package.json index dd39138a18..56a0bb69e9 100644 --- a/developer/js/package.json +++ b/developer/js/package.json @@ -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", diff --git a/lerna.json b/lerna.json index 214aa59f39..8057db79ec 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "lerna", "typescript" ], - "version": "14.0.153" + "version": "14.0.155" } diff --git a/resources/build/version/package-lock.json b/resources/build/version/package-lock.json index c5a26cbfae..2fcb0a27ae 100644 --- a/resources/build/version/package-lock.json +++ b/resources/build/version/package-lock.json @@ -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", diff --git a/resources/build/version/package.json b/resources/build/version/package.json index a7c7bfa5c8..51c3f13885 100644 --- a/resources/build/version/package.json +++ b/resources/build/version/package.json @@ -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" diff --git a/resources/git-hooks/prepare-commit-msg b/resources/git-hooks/prepare-commit-msg index 021a71a5f5..a43bb8206a 100755 --- a/resources/git-hooks/prepare-commit-msg +++ b/resources/git-hooks/prepare-commit-msg @@ -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. diff --git a/resources/gosh/package-lock.json b/resources/gosh/package-lock.json index 390cfe9676..58ab6d723e 100644 --- a/resources/gosh/package-lock.json +++ b/resources/gosh/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1 } diff --git a/resources/gosh/package.json b/resources/gosh/package.json index 460adc1df2..113d6d4c26 100644 --- a/resources/gosh/package.json +++ b/resources/gosh/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/resources-gosh", - "version": "14.0.153", + "version": "14.0.155", "description": "Good Ol' Shell", "author": "Marc Durdin (https://github.com/mcdurdin)", "contributors": [ diff --git a/resources/web-environment/package-lock.json b/resources/web-environment/package-lock.json index 653c9d058d..7144802e22 100644 --- a/resources/web-environment/package-lock.json +++ b/resources/web-environment/package-lock.json @@ -1,5 +1,5 @@ { "name": "@keymanapp/web-environment", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1 } diff --git a/resources/web-environment/package.json b/resources/web-environment/package.json index 285f3f581d..64604cef40 100644 --- a/resources/web-environment/package.json +++ b/resources/web-environment/package.json @@ -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 (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" } } diff --git a/web/package-lock.json b/web/package-lock.json index b2d898abe3..e0cec38520 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.153", + "version": "14.0.155", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/web/package.json b/web/package.json index 7d28c69248..1e91dafbd2 100644 --- a/web/package.json +++ b/web/package.json @@ -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", diff --git a/windows/src/Makefile b/windows/src/Makefile index 1d6e3e8a5c..d89939aa84 100644 --- a/windows/src/Makefile +++ b/windows/src/Makefile @@ -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 diff --git a/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas b/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas index f8ab24439e..faad0d9454 100644 --- a/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas +++ b/windows/src/desktop/kmshell/main/Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas @@ -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); @@ -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; + 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. diff --git a/windows/src/developer/kmcmpdll/Compiler.cpp b/windows/src/developer/kmcmpdll/Compiler.cpp index 7125203d02..4eb236deaf 100644 --- a/windows/src/developer/kmcmpdll/Compiler.cpp +++ b/windows/src/developer/kmcmpdll/Compiler.cpp @@ -97,7 +97,7 @@ BOOL IsSameToken(PWSTR *p, PWSTR token); DWORD GetRHS(PFILE_KEYBOARD fk, PWSTR p, PWSTR buf, int bufsize, int offset, int IsUnicode); PWSTR GetDelimitedString(PWSTR *p, PWSTR Delimiters, WORD Flags); DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int max, int offset, PWSTR *newp, int isVKey, - int isUnicode); + int isUnicode); int GetGroupNum(PFILE_KEYBOARD fk, PWSTR p); int LineTokenType(PWSTR *str); @@ -141,44 +141,44 @@ BOOL IsValidKeyboardVersion(WCHAR *dpString); // I4140 HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble); const PWCHAR LineTokens[] = { - L"SVNBHBGMNSCCLLCMLB", L"store", L"VERSION ", L"NAME ", - L"BITMAP ", L"HOTKEY ", L"begin", L"group", L"match", L"nomatch", - L"SHIFT FREES CAPS", L"CAPS ON ONLY", L"CAPS ALWAYS OFF", - L"LANGUAGE ", L"LAYOUT ", L"COPYRIGHT ", L"MESSAGE ", L"LANGUAGENAME ", - L"BITMAPS " }; + L"SVNBHBGMNSCCLLCMLB", L"store", L"VERSION ", L"NAME ", + L"BITMAP ", L"HOTKEY ", L"begin", L"group", L"match", L"nomatch", + L"SHIFT FREES CAPS", L"CAPS ON ONLY", L"CAPS ALWAYS OFF", + L"LANGUAGE ", L"LAYOUT ", L"COPYRIGHT ", L"MESSAGE ", L"LANGUAGENAME ", + L"BITMAPS " }; #define SSN__PREFIX L"&" -const PWCHAR StoreTokens[TSS__MAX+2] = { - L"", - SSN__PREFIX L"BITMAP", - SSN__PREFIX L"COPYRIGHT", - SSN__PREFIX L"HOTKEY", - SSN__PREFIX L"LANGUAGE", - SSN__PREFIX L"LAYOUT", - SSN__PREFIX L"MESSAGE", - SSN__PREFIX L"NAME", - SSN__PREFIX L"VERSION", - SSN__PREFIX L"CAPSONONLY", - SSN__PREFIX L"CAPSALWAYSOFF", - SSN__PREFIX L"SHIFTFREESCAPS", - SSN__PREFIX L"LANGUAGENAME", - L"", - L"", - SSN__PREFIX L"ETHNOLOGUECODE", - L"", - SSN__PREFIX L"MNEMONICLAYOUT", - SSN__PREFIX L"INCLUDECODES", - SSN__PREFIX L"OLDCHARPOSMATCHING", - L"", - L"", - L"", - L"", - SSN__PREFIX L"VISUALKEYBOARD", - SSN__PREFIX L"KMW_RTL", - SSN__PREFIX L"KMW_HELPFILE", - SSN__PREFIX L"KMW_HELPTEXT", - SSN__PREFIX L"KMW_EMBEDJS", +const PWCHAR StoreTokens[TSS__MAX + 2] = { + L"", + SSN__PREFIX L"BITMAP", + SSN__PREFIX L"COPYRIGHT", + SSN__PREFIX L"HOTKEY", + SSN__PREFIX L"LANGUAGE", + SSN__PREFIX L"LAYOUT", + SSN__PREFIX L"MESSAGE", + SSN__PREFIX L"NAME", + SSN__PREFIX L"VERSION", + SSN__PREFIX L"CAPSONONLY", + SSN__PREFIX L"CAPSALWAYSOFF", + SSN__PREFIX L"SHIFTFREESCAPS", + SSN__PREFIX L"LANGUAGENAME", + L"", + L"", + SSN__PREFIX L"ETHNOLOGUECODE", + L"", + SSN__PREFIX L"MNEMONICLAYOUT", + SSN__PREFIX L"INCLUDECODES", + SSN__PREFIX L"OLDCHARPOSMATCHING", + L"", + L"", + L"", + L"", + SSN__PREFIX L"VISUALKEYBOARD", + SSN__PREFIX L"KMW_RTL", + SSN__PREFIX L"KMW_HELPFILE", + SSN__PREFIX L"KMW_HELPTEXT", + SSN__PREFIX L"KMW_EMBEDJS", SSN__PREFIX L"WINDOWSLANGUAGES", L"", SSN__PREFIX L"PLATFORM", // read only // I3430 @@ -187,9 +187,9 @@ const PWCHAR StoreTokens[TSS__MAX+2] = { L"", // I3438 SSN__PREFIX L"LAYOUTFILE", // I3483 SSN__PREFIX L"KEYBOARDVERSION", // I4140 - SSN__PREFIX L"KMW_EMBEDCSS", + SSN__PREFIX L"KMW_EMBEDCSS", SSN__PREFIX L"TARGETS", // I4504 - NULL + NULL }; HINSTANCE g_hInstance; @@ -198,7 +198,7 @@ int currentLine = 0, nErrors = 0; char CompileDir[MAX_PATH]; int ErrChr; char ErrExtra[256]; -BOOL FSaveDebug, FCompilerWarningsAsErrors, FWarnDeprecatedCode; // I4865 // I4866 +BOOL FSaveDebug, FCompilerWarningsAsErrors, FWarnDeprecatedCode; // I4865 // I4866 BOOL FOldCharPosMatching = FALSE, FMnemonicLayout = FALSE; NamedCodeConstants *CodeConstants = NULL; @@ -212,343 +212,342 @@ int CompileTarget; BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved) { - if(fdwReason == DLL_PROCESS_ATTACH) g_hInstance = hinst; - return TRUE; + if (fdwReason == DLL_PROCESS_ATTACH) g_hInstance = hinst; + return TRUE; } PWSTR strtowstr(PSTR in) { - PWSTR result; - size_t len; + PWSTR result; + size_t len; - mbstowcs_s(&len, NULL, 0, in, strlen(in)); // I3481 - result = new WCHAR[len+1]; - mbstowcs_s(&len, result, len+1, in, strlen(in)); // I3481 // I3641 - result[len] = 0; - return result; + mbstowcs_s(&len, NULL, 0, in, strlen(in)); // I3481 + result = new WCHAR[len + 1]; + mbstowcs_s(&len, result, len + 1, in, strlen(in)); // I3481 // I3641 + result[len] = 0; + return result; } PSTR wstrtostr(PWSTR in) { - PSTR result; - size_t len; + PSTR result; + size_t len; - wcstombs_s(&len, NULL, 0, in, wcslen(in)); // I3481 - result = new CHAR[len+1]; - wcstombs_s(&len, result, len+1, in, wcslen(in)); // I3481 // I3641 - result[len] = 0; - return result; + wcstombs_s(&len, NULL, 0, in, wcslen(in)); // I3481 + result = new CHAR[len + 1]; + wcstombs_s(&len, result, len + 1, in, wcslen(in)); // I3481 // I3641 + result[len] = 0; + return result; } BOOL AddCompileString(LPSTR buf) { - SetLastError(0); - (*msgproc)(currentLine+1, CWARN_Info, buf); - return FALSE; + SetLastError(0); + (*msgproc)(currentLine + 1, CWARN_Info, buf); + return FALSE; } BOOL AddCompileMessage(DWORD msg) { - char szText[SZMAX_ERRORTEXT+1+280]; + char szText[SZMAX_ERRORTEXT + 1 + 280]; - SetLastError(0); - if(msg & CERR_MEMORY) - { - lstrcpy(szText, "Fatal Error: Out of Memory"); - (*msgproc)(currentLine+1, msg, szText); - nErrors++; - return TRUE; - } + SetLastError(0); + if (msg & CERR_MEMORY) + { + lstrcpy(szText, "Fatal Error: Out of Memory"); + (*msgproc)(currentLine + 1, msg, szText); + nErrors++; + return TRUE; + } - if(msg & CERR_FATAL) - { - LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); - (*msgproc)(currentLine+1, msg, szText); - nErrors++; - return TRUE; - } + if (msg & CERR_FATAL) + { + LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); + (*msgproc)(currentLine + 1, msg, szText); + nErrors++; + return TRUE; + } - if(msg & CERR_ERROR) nErrors++; - LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); - if(ErrChr > 0) - wsprintf(strchr(szText, 0), " chr:%d", ErrChr); - if(*ErrExtra) - wsprintf(strchr(szText, 0), " extra:%s", ErrExtra); + if (msg & CERR_ERROR) nErrors++; + LoadString(g_hInstance, msg, szText, SZMAX_ERRORTEXT); + if (ErrChr > 0) + wsprintf(strchr(szText, 0), " chr:%d", ErrChr); + if (*ErrExtra) + wsprintf(strchr(szText, 0), " extra:%s", ErrExtra); - ErrChr = 0; *ErrExtra = 0; + ErrChr = 0; *ErrExtra = 0; - if(!(*msgproc)(currentLine, msg, szText)) return TRUE; + if (!(*msgproc)(currentLine, msg, szText)) return TRUE; - return FALSE; + return FALSE; } 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; - BOOL err; - DWORD len; - char str[260]; + HANDLE hInfile = INVALID_HANDLE_VALUE, hOutfile = INVALID_HANDLE_VALUE; + BOOL err; + DWORD len; + char str[260]; - FSaveDebug = ASaveDebug; + FSaveDebug = ASaveDebug; FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 FWarnDeprecatedCode = AWarnDeprecatedCode; // I4866 CompileTarget = CKF_KEYMAN; - if(!pMsgProc) SetError(CERR_BadCallParams); + if (!pMsgProc || !pszInfile || !pszOutfile) SetError(CERR_BadCallParams); - PSTR p; - if(p = strrchr(pszInfile, '\\')) - { - strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p-pszInfile+1)); // I3481 - CompileDir[(INT_PTR)(p-pszInfile+1)] = 0; - } - else - CompileDir[0] = 0; + PSTR p; + if (p = strrchr(pszInfile, '\\')) + { + strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p - pszInfile + 1)); // I3481 + CompileDir[(INT_PTR)(p - pszInfile + 1)] = 0; + } + else + CompileDir[0] = 0; - msgproc = pMsgProc; - currentLine = 0; - nErrors = 0; + msgproc = pMsgProc; + currentLine = 0; + nErrors = 0; - if(!pszInfile || !pszOutfile) SetError(CERR_BadCallParams); + hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); - hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hInfile == INVALID_HANDLE_VALUE) 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... - // 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(!ReadFile(hInfile, str, 3, &len, NULL)) - { - CloseHandle(hInfile); - return CERR_CannotReadInfile; - } - SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); - if(str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) - hInfile = UTF16TempFromUTF8(hInfile, TRUE); - else if(str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) - SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); - else - hInfile = UTF16TempFromUTF8(hInfile, FALSE); // Will fall back to ansi for invalid UTF-8 - if(hInfile == INVALID_HANDLE_VALUE) // I3228 // I3510 + if (!ReadFile(hInfile, str, 3, &len, NULL)) + { + CloseHandle(hInfile); + return CERR_CannotReadInfile; + } + SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); + if (str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) + hInfile = UTF16TempFromUTF8(hInfile, TRUE); + else if (str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) + SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); + else + hInfile = UTF16TempFromUTF8(hInfile, FALSE); // Will fall back to ansi for invalid UTF-8 + if (hInfile == INVALID_HANDLE_VALUE) // I3228 // I3510 { return CERR_CannotCreateTempfile; } - hOutfile = CreateFileA(pszOutfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - if(hOutfile == INVALID_HANDLE_VALUE) SetError(CERR_CannotCreateOutfile); + hOutfile = CreateFileA(pszOutfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if (hOutfile == INVALID_HANDLE_VALUE) SetError(CERR_CannotCreateOutfile); - DWORD msg; - FILE_KEYBOARD fk; - CodeConstants = new NamedCodeConstants; + DWORD msg; + FILE_KEYBOARD fk; + CodeConstants = new NamedCodeConstants; - err = CompileKeyboardHandle(hInfile, &fk); - if(err) - { - if((msg = WriteCompiledKeyboard(&fk, hOutfile)) != CERR_None) - AddCompileMessage(msg); - } - else - AddCompileMessage(CERR_InvalidValue); + err = CompileKeyboardHandle(hInfile, &fk); + if (err) + { + if ((msg = WriteCompiledKeyboard(&fk, hOutfile)) != CERR_None) + AddCompileMessage(msg); + } + else + AddCompileMessage(CERR_InvalidValue); - CloseHandle(hInfile); - CloseHandle(hOutfile); + CloseHandle(hInfile); + CloseHandle(hOutfile); - delete CodeConstants; + delete CodeConstants; - if(nErrors > 0) - { - DeleteFile(pszOutfile); - return FALSE; - } + if (nErrors > 0) + { + DeleteFile(pszOutfile); + return FALSE; + } - return err; + return err; } extern "C" BOOL __declspec(dllexport) CompileKeyboardFileToBuffer(PSTR pszInfile, PFILE_KEYBOARD pfkBuffer, BOOL ACompilerWarningsAsErrors, BOOL AWarnDeprecatedCode, CompilerMessageProc pMsgProc, int Target) // I4865 // I4866 { - HANDLE hInfile = INVALID_HANDLE_VALUE; - BOOL err; - DWORD len; - char str[260]; + HANDLE hInfile = INVALID_HANDLE_VALUE; + BOOL err; + DWORD len; + char str[260]; - FSaveDebug = TRUE; // I3681 + FSaveDebug = TRUE; // I3681 FCompilerWarningsAsErrors = ACompilerWarningsAsErrors; // I4865 FWarnDeprecatedCode = AWarnDeprecatedCode; // I4866 CompileTarget = Target; - if(!pMsgProc) SetError(CERR_BadCallParams); + if (!pMsgProc || !pszInfile || !pfkBuffer) SetError(CERR_BadCallParams); - PSTR p; - if(p = strrchr(pszInfile, '\\')) - { - strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p-pszInfile+1)); // I3481 - CompileDir[(INT_PTR)(p-pszInfile+1)] = 0; - } - else - CompileDir[0] = 0; + PSTR p; + if (p = strrchr(pszInfile, '\\')) + { + strncpy_s(CompileDir, _countof(CompileDir), pszInfile, (INT_PTR)(p - pszInfile + 1)); // I3481 + CompileDir[(INT_PTR)(p - pszInfile + 1)] = 0; + } + else + CompileDir[0] = 0; - msgproc = pMsgProc; - currentLine = 0; - nErrors = 0; + msgproc = pMsgProc; + currentLine = 0; + nErrors = 0; - if(!pszInfile || !pfkBuffer) SetError(CERR_BadCallParams); + hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hInfile == INVALID_HANDLE_VALUE) SetError(CERR_InfileNotExist); - hInfile = CreateFileA(pszInfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hInfile == INVALID_HANDLE_VALUE) 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... - // 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 (!ReadFile(hInfile, str, 3, &len, NULL)) + { + CloseHandle(hInfile); + return CERR_CannotReadInfile; + } + SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); + if (str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) + hInfile = UTF16TempFromUTF8(hInfile, TRUE); + else if (str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) + SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); + else + hInfile = UTF16TempFromUTF8(hInfile, FALSE); - if(!ReadFile(hInfile, str, 3, &len, NULL)) - { - CloseHandle(hInfile); - return CERR_CannotReadInfile; - } - SetFilePointer(hInfile, 0, NULL, FILE_BEGIN); - if(str[0] == UTF8Sig[0] && str[1] == UTF8Sig[1] && str[2] == UTF8Sig[2]) - hInfile = UTF16TempFromUTF8(hInfile, TRUE); - else if(str[0] == UTF16Sig[0] && str[1] == UTF16Sig[1]) - SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); - else - hInfile = UTF16TempFromUTF8(hInfile, FALSE); + CodeConstants = new NamedCodeConstants; + err = CompileKeyboardHandle(hInfile, pfkBuffer); + delete CodeConstants; + CloseHandle(hInfile); - CodeConstants = new NamedCodeConstants; - err = CompileKeyboardHandle(hInfile, pfkBuffer); - delete CodeConstants; - CloseHandle(hInfile); + if (nErrors > 0) + return FALSE; - if(nErrors > 0) - return FALSE; - - return err; + return err; } void GetVersionInfo(DWORD *VersionMajor, DWORD *VersionMinor) { - HRSRC hres = FindResource(0, MAKEINTRESOURCE(1), RT_VERSION); - if(hres) - { - HGLOBAL hmem = LoadResource(0, hres); - PSTR buf = (PSTR) LockResource(hmem); - *VersionMajor = *((PDWORD) &buf[0x30]); - *VersionMinor = *((PDWORD) &buf[0x34]); - } + HRSRC hres = FindResource(0, MAKEINTRESOURCE(1), RT_VERSION); + if (hres) + { + HGLOBAL hmem = LoadResource(0, hres); + PSTR buf = (PSTR)LockResource(hmem); + *VersionMajor = *((PDWORD)&buf[0x30]); + *VersionMinor = *((PDWORD)&buf[0x34]); + } } BOOL CompileKeyboardHandle(HANDLE hInfile, PFILE_KEYBOARD fk) { - PWSTR str, p; + PWSTR str, p; - DWORD msg; + DWORD msg; - FMnemonicLayout = FALSE; + FMnemonicLayout = FALSE; - str = new WCHAR[LINESIZE]; - if(!str) SetError(CERR_CannotAllocateMemory); + if (!fk) { + SetError(CERR_SomewhereIGotItWrong); + } - //fk = new FILE_KEYBOARD; - if(!fk) SetError(CERR_CannotAllocateMemory); + str = new 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->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; + fk->szLanguageName[0] = 0;*/ + fk->dwBitmapSize = 0; + fk->dwHotKey = 0; - /* Add a store for the Keyman 6.0 copyright information string */ + /* Add a store for the Keyman 6.0 copyright information string */ - DWORD vmajor, vminor; - GetVersionInfo(&vmajor, &vminor); - //char buf[256]; - swprintf(str, LINESIZE, L"Created with Keyman Developer version %d.%d.%d.%d", HIWORD(vmajor), - LOWORD(vmajor), HIWORD(vminor), LOWORD(vminor)); // I3481 + DWORD vmajor, vminor; + GetVersionInfo(&vmajor, &vminor); + //char buf[256]; + swprintf(str, LINESIZE, L"Created with Keyman Developer version %d.%d.%d.%d", HIWORD(vmajor), + LOWORD(vmajor), HIWORD(vminor), LOWORD(vminor)); // I3481 - //PWSTR pw = strtowstr(buf); - AddStore(fk, TSS_KEYMANCOPYRIGHT, str); - //delete pw; +//PWSTR pw = strtowstr(buf); + AddStore(fk, TSS_KEYMANCOPYRIGHT, str); + //delete pw; - /* Add a system store for the Keyman edition number */ + /* Add a system store for the Keyman edition number */ - swprintf(str, LINESIZE, L"%d", 0); // I3481 - AddStore(fk, TSS_CUSTOMKEYMANEDITION, str); - PWSTR tbuf = strtowstr((char*) "Keyman"); - AddStore(fk, TSS_CUSTOMKEYMANEDITIONNAME, tbuf); - delete tbuf; + swprintf(str, LINESIZE, L"%d", 0); // I3481 + AddStore(fk, TSS_CUSTOMKEYMANEDITION, str); + PWSTR tbuf = strtowstr((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(hInfile, str, TRUE)) == CERR_None) + // must preprocess for group and store names -> this isn't really necessary, but never mind! + while ((msg = ReadLine(hInfile, str, TRUE)) == CERR_None) + { + if (GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); + p = str; + switch (LineTokenType(&p)) { - if(GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); - 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_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_GROUP: + if ((msg = ProcessGroupLine(fk, p)) != CERR_None) SetError(msg); + break; - case T_STORE: - if((msg = ProcessStoreLine(fk, p)) != CERR_None) SetError(msg); - break; + case T_STORE: + if ((msg = ProcessStoreLine(fk, p)) != CERR_None) SetError(msg); + break; - default: - break; - } - } + default: + break; + } + } - if(msg != CERR_EndOfFile) SetError(msg); + if (msg != CERR_EndOfFile) SetError(msg); - SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); - currentLine = 0; + SetFilePointer(hInfile, 2, NULL, FILE_BEGIN); + currentLine = 0; - /* Reindex the list of codeconstants after stores added */ + /* Reindex the list of codeconstants after stores added */ - CodeConstants->reindex(); + CodeConstants->reindex(); - /* ReadLine will automatically skip over $Keyman lines, and parse wrapped lines */ - while((msg = ReadLine(hInfile, str, FALSE)) == CERR_None) - { - if(GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); - msg = ParseLine(fk, str); - if(msg != CERR_None) SetError(msg); - } + /* ReadLine will automatically skip over $Keyman lines, and parse wrapped lines */ + while ((msg = ReadLine(hInfile, str, FALSE)) == CERR_None) + { + if (GetAsyncKeyState(VK_ESCAPE) < 0) SetError(CERR_Break); + msg = ParseLine(fk, str); + if (msg != CERR_None) SetError(msg); + } - if(msg != CERR_EndOfFile) SetError(msg); + if (msg != CERR_EndOfFile) SetError(msg); - ProcessGroupFinish(fk); + ProcessGroupFinish(fk); - if(FSaveDebug) RecordDeadkeyNames(fk); + if (FSaveDebug) RecordDeadkeyNames(fk); - /* Add the compiler version as a system store */ - if((msg = AddCompilerVersionStore(fk)) != CERR_None) SetError(msg); + /* Add the compiler version as a system store */ + if ((msg = AddCompilerVersionStore(fk)) != CERR_None) SetError(msg); - if((msg = BuildVKDictionary(fk)) != CERR_None) SetError(msg); // I3438 + if ((msg = BuildVKDictionary(fk)) != CERR_None) SetError(msg); // I3438 - delete str; + delete str; if (!CheckKeyboardFinalVersion(fk)) { return FALSE; @@ -562,37 +561,37 @@ BOOL CompileKeyboardHandle(HANDLE hInfile, PFILE_KEYBOARD fk) DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PWSTR p) { - WCHAR tstr[128]; - PWSTR q, pp; - int BeginMode; - DWORD msg; + WCHAR tstr[128]; + PWSTR q, pp; + int BeginMode; + DWORD msg; - pp = p; + pp = p; - q = wcschr(p, '>'); - if(!q) return CERR_NoTokensFound; + q = wcschr(p, '>'); + if (!q) return CERR_NoTokensFound; - while(iswspace(*p)) p++; - if(_wcsnicmp(p, L"unicode", 7) == 0) BeginMode = BEGIN_UNICODE; - else if(_wcsnicmp(p, L"ansi", 4) == 0) BeginMode = BEGIN_ANSI; - else if(*p != '>') return CERR_InvalidToken; - else BeginMode = BEGIN_ANSI; + while (iswspace(*p)) p++; + if (_wcsnicmp(p, L"unicode", 7) == 0) BeginMode = BEGIN_UNICODE; + else if (_wcsnicmp(p, L"ansi", 4) == 0) BeginMode = BEGIN_ANSI; + else if (*p != '>') return CERR_InvalidToken; + else BeginMode = BEGIN_ANSI; - if((msg = GetRHS(fk, p, tstr, 80, (int)(INT_PTR)(p-pp), FALSE)) != CERR_None) return msg; + if ((msg = GetRHS(fk, p, tstr, 80, (int)(INT_PTR)(p - pp), FALSE)) != CERR_None) return msg; - if(tstr[0] != UC_SENTINEL || tstr[1] != CODE_USE) return CERR_InvalidBegin; + if (tstr[0] != UC_SENTINEL || tstr[1] != CODE_USE) return CERR_InvalidBegin; - 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(tstr[3] != 0) return CERR_InvalidToken; + 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 (tstr[3] != 0) return CERR_InvalidToken; - if(FSaveDebug) - /* Record a system store for the line number of the begin statement */ - AddDebugStore(fk, BeginMode == BEGIN_UNICODE ? DEBUGSTORE_BEGIN L"Unicode" : DEBUGSTORE_BEGIN L"ANSI"); + if (FSaveDebug) + /* Record a system store for the line number of the begin statement */ + AddDebugStore(fk, BeginMode == BEGIN_UNICODE ? DEBUGSTORE_BEGIN L"Unicode" : DEBUGSTORE_BEGIN L"ANSI"); - return CERR_None; + return CERR_None; } DWORD ValidateMatchNomatchOutput(PWSTR p) { @@ -612,181 +611,147 @@ DWORD ValidateMatchNomatchOutput(PWSTR p) { DWORD ParseLine(PFILE_KEYBOARD fk, PWSTR str) { - PWSTR p, q, pp; - PFILE_GROUP gp; - DWORD msg; - int IsUnicode = TRUE; // For NOW! + PWSTR p, q, pp; + PFILE_GROUP gp; + DWORD msg; + int IsUnicode = TRUE; // For NOW! - p = str; - pp = str; + p = str; + pp = str; - switch(LineTokenType(&p)) + 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 { - case T_BLANK: - case T_COMMENT: - break; // Ignore the line - case T_VERSION: - case T_STORE: - break; // The line has already been processed + 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_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: + case T_NAME: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if( !q ) return CERR_InvalidName; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidName; - if((msg = AddStore(fk, TSS_NAME, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_NAME, q)) != CERR_None) return msg; + break; - case T_COPYRIGHT: + case T_COPYRIGHT: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if(!q) return CERR_InvalidCopyright; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidCopyright; - if((msg = AddStore(fk, TSS_COPYRIGHT, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_COPYRIGHT, q)) != CERR_None) return msg; + break; case T_MESSAGE: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if(!q) return CERR_InvalidMessage; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidMessage; - if((msg = AddStore(fk, TSS_MESSAGE, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_MESSAGE, q)) != CERR_None) return msg; + break; - case T_LANGUAGENAME: + case T_LANGUAGENAME: WarnDeprecatedHeader(); // I4866 - q = GetDelimitedString(&p, L"\"\"", 0); - if(!q) return CERR_InvalidLanguageName; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidLanguageName; - if((msg = AddStore(fk, TSS_LANGUAGENAME, q)) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_LANGUAGENAME, q)) != CERR_None) return msg; + break; - case T_LANGUAGE: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - q = wcstok_s(p, L"\n", &tokcontext); // I3481 - if((msg = AddStore(fk, TSS_LANGUAGE, q)) != CERR_None) return msg; - break; - } - case T_LAYOUT: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - q = wcstok_s(p, L"\n", &tokcontext); // I3481 - if((msg = AddStore(fk, TSS_LAYOUT, q)) != CERR_None) return msg; - break; - } - case T_CAPSOFF: + case T_LANGUAGE: + { WarnDeprecatedHeader(); // I4866 - if((msg = AddStore(fk, TSS_CAPSALWAYSOFF, L"1")) != CERR_None) return msg; - break; - - case T_CAPSON: + wchar_t *tokcontext = NULL; + q = wcstok_s(p, L"\n", &tokcontext); // I3481 + if ((msg = AddStore(fk, TSS_LANGUAGE, q)) != CERR_None) return msg; + break; + } + case T_LAYOUT: + { WarnDeprecatedHeader(); // I4866 - if((msg = AddStore(fk, TSS_CAPSONONLY, L"1")) != CERR_None) return msg; - break; - - case T_SHIFT: + wchar_t *tokcontext = NULL; + q = wcstok_s(p, L"\n", &tokcontext); // I3481 + if ((msg = AddStore(fk, TSS_LAYOUT, q)) != CERR_None) return msg; + break; + } + case T_CAPSOFF: WarnDeprecatedHeader(); // I4866 - if((msg = AddStore(fk, TSS_SHIFTFREESCAPS, L"1")) != CERR_None) return msg; - break; + if ((msg = AddStore(fk, TSS_CAPSALWAYSOFF, L"1")) != CERR_None) return msg; + break; - case T_HOTKEY: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - if((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_CodeInvalidInThisSection; // I3481 - if((msg = AddStore(fk, TSS_HOTKEY, q)) != CERR_None) return msg; - break; + case T_CAPSON: + WarnDeprecatedHeader(); // I4866 + if ((msg = AddStore(fk, TSS_CAPSONONLY, L"1")) != CERR_None) return msg; + break; + + case T_SHIFT: + WarnDeprecatedHeader(); // I4866 + if ((msg = AddStore(fk, TSS_SHIFTFREESCAPS, L"1")) != CERR_None) return msg; + break; + + case T_HOTKEY: + { + WarnDeprecatedHeader(); // I4866 + wchar_t *tokcontext = NULL; + if ((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_CodeInvalidInThisSection; // I3481 + if ((msg = AddStore(fk, TSS_HOTKEY, q)) != CERR_None) return msg; + break; + } + case T_BITMAP: + { + WarnDeprecatedHeader(); // I4866 + wchar_t *tokcontext = NULL; + if ((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + + while (iswspace(*q)) q++; + if (*q == '"') { + p = q; + q = GetDelimitedString(&p, L"\"\"", 0); + if (!q) return CERR_InvalidBitmapLine; } - case T_BITMAP: + + if ((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; + break; + } + case T_BITMAPS: + { + WarnDeprecatedHeader(); // I4866 + wchar_t *tokcontext = NULL; + AddWarning(CWARN_BitmapNotUsed); + + if ((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + if (wcschr(q, ',')) *wcschr(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; { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - if((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 - - while(iswspace(*q)) q++; - if(*q == '"') { p = q; q = GetDelimitedString(&p, L"\"\"", 0); } - - if((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; - break; - } - case T_BITMAPS: - { - WarnDeprecatedHeader(); // I4866 - wchar_t *tokcontext = NULL; - AddWarning(CWARN_BitmapNotUsed); - - if((q = wcstok_s(p, L"\n", &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 - if(wcschr(q, ',')) *wcschr(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; - { - PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; - if((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(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 WCHAR[wcslen(buf) + 1]; - wcscpy_s(gp->dpMatch, wcslen(buf)+1, buf); // I3481 - - delete buf; - - if(FSaveDebug) - { - WCHAR tstr[128]; - //char buf[256]; - //swprintf(tstr, "%d", fk->currentGroup); - /* Record a system store for the line number of the begin statement */ - //wcscpy(tstr, DEBUGSTORE_MATCH); - - //wcscat(tstr, pw); - - swprintf(tstr, _countof(tstr), L"%s%d %s", DEBUGSTORE_MATCH, fk->currentGroup, gp->szName); // I3481 - AddDebugStore(fk, tstr); - } - } - break; - - case T_NOMATCH: - if(fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; - { - PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; - if((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE, (int)(INT_PTR)(p-pp), IsUnicode)) != CERR_None) + PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(p - pp), IsUnicode)) != CERR_None) { delete buf; return msg; @@ -797,72 +762,110 @@ DWORD ParseLine(PFILE_KEYBOARD fk, PWSTR str) return msg; } - gp = &fk->dpGroupArray[fk->currentGroup]; + gp = &fk->dpGroupArray[fk->currentGroup]; - gp->dpNoMatch = new WCHAR[wcslen(buf) + 1]; - wcscpy_s(gp->dpNoMatch, wcslen(buf)+1, buf); // I3481 + gp->dpMatch = new WCHAR[wcslen(buf) + 1]; + wcscpy_s(gp->dpMatch, wcslen(buf) + 1, buf); // I3481 - delete buf; + delete buf; - if(FSaveDebug) - { - WCHAR tstr[128]; - /* Record a system store for the line number of the begin statement */ - swprintf(tstr, _countof(tstr), L"%s%d %s", DEBUGSTORE_NOMATCH, fk->currentGroup, gp->szName); // I3481 - AddDebugStore(fk, tstr); - } - } - break; + if (FSaveDebug) + { + WCHAR tstr[128]; + //char buf[256]; + //swprintf(tstr, "%d", fk->currentGroup); + /* Record a system store for the line number of the begin statement */ + //wcscpy(tstr, DEBUGSTORE_MATCH); - default: - return CERR_InvalidToken; - } + //wcscat(tstr, pw); - return CERR_None; + swprintf(tstr, _countof(tstr), L"%ls%d %ls", DEBUGSTORE_MATCH, (int) fk->currentGroup, gp->szName); // I3481 + AddDebugStore(fk, tstr); + } + } + break; + + case T_NOMATCH: + if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + { + PWCHAR buf = new WCHAR[GLOBAL_BUFSIZE]; + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE, (int)(INT_PTR)(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 WCHAR[wcslen(buf) + 1]; + wcscpy_s(gp->dpNoMatch, wcslen(buf) + 1, buf); // I3481 + + delete[] buf; + + if (FSaveDebug) + { + WCHAR tstr[128]; + /* Record a system store for the line number of the begin statement */ + swprintf(tstr, _countof(tstr), L"%ls%d %ls", DEBUGSTORE_NOMATCH, fk->currentGroup, gp->szName); // I3481 + AddDebugStore(fk, tstr); + } + } + break; + + default: + return CERR_InvalidToken; + } + + return CERR_None; } //********************************************************************************************************************** DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PWSTR p) { - PFILE_GROUP gp; - PWSTR q; + PFILE_GROUP gp; + PWSTR q; - gp = new FILE_GROUP[fk->cxGroupArray + 1]; - if(!gp) return CERR_CannotAllocateMemory; + 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; - } + 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++; + fk->dpGroupArray = gp; + gp = &fk->dpGroupArray[fk->cxGroupArray]; + fk->cxGroupArray++; - gp->dpKeyArray = NULL; - gp->dpMatch = NULL; - gp->dpNoMatch = NULL; - gp->cxKeyArray = 0; + gp->dpKeyArray = NULL; + gp->dpMatch = NULL; + gp->dpNoMatch = NULL; + gp->cxKeyArray = 0; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q) return CERR_InvalidGroupLine; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q) return CERR_InvalidGroupLine; - gp->fUsingKeys = FALSE; - if(IsSameToken(&p, L"using") && IsSameToken(&p, L"keys")) gp->fUsingKeys = TRUE; + gp->fUsingKeys = FALSE; + if (IsSameToken(&p, L"using") && IsSameToken(&p, L"keys")) gp->fUsingKeys = TRUE; - safe_wcsncpy(gp->szName, q, SZMAX_GROUPNAME); + safe_wcsncpy(gp->szName, q, SZMAX_GROUPNAME); - if(FSaveDebug) - { - WCHAR tstr[128]; - /* Record a system store for the line number of the begin statement */ - swprintf(tstr, _countof(tstr), L"%s%d %s", DEBUGSTORE_GROUP, fk->cxGroupArray-1, gp->szName); // I3481 - AddDebugStore(fk, tstr); - } + if (FSaveDebug) + { + WCHAR tstr[128]; + /* Record a system store for the line number of the begin statement */ + swprintf(tstr, _countof(tstr), L"%ls%d %ls", DEBUGSTORE_GROUP, fk->cxGroupArray - 1, gp->szName); // I3481 + AddDebugStore(fk, tstr); + } - return CERR_None; + return CERR_None; } /* Following code lifted from syskbd.cpp and tweaked for compiler use. Todo: consolidate */ @@ -882,104 +885,104 @@ DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PWSTR p) WCHAR VKToChar(WORD keyCode, UINT shiftFlags) { - char shiftedDigit[] = ")!@#$%^&*("; - int n, Shift; + char shiftedDigit[] = ")!@#$%^&*("; + int n, Shift; - if(!(shiftFlags & ISVIRTUALKEY)) return keyCode; + if (!(shiftFlags & ISVIRTUALKEY)) return keyCode; - if(shiftFlags & (LCTRLFLAG|RCTRLFLAG|LALTFLAG|RALTFLAG)) return 0; + 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 >= '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 >= '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'); - } + if (keyCode >= VK_NUMPAD0 && keyCode <= VK_NUMPAD9) + { + if (!(shiftFlags & NUMLOCKFLAG)) return 0; + return keyCode - (VK_NUMPAD0 - '0'); + } - Shift = (shiftFlags & K_SHIFTFLAG); + 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; + 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; } int cmpkeys(const void *key, const void *elem) { - PFILE_KEY akey, aelem; - int l1, l2; + PFILE_KEY akey, aelem; + int l1, l2; WCHAR char_key, char_elem; - akey = (PFILE_KEY)key; - aelem = (PFILE_KEY)elem; + akey = (PFILE_KEY)key; + aelem = (PFILE_KEY)elem; char_key = VKToChar(akey->Key, akey->ShiftFlags); char_elem = VKToChar(aelem->Key, aelem->ShiftFlags); - if(char_key == char_elem) //akey->Key == aelem->Key) + if (char_key == char_elem) //akey->Key == aelem->Key) + { + l1 = xstrlen(akey->dpContext); l2 = xstrlen(aelem->dpContext); + if (l1 == l2) { - 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; - return 0; - } - if(l1 < l2) return 1; - if(l1 > l2) return -1; - } - return(char_key - char_elem); // akey->Key - aelem->Key); + if (akey->Line < aelem->Line) return -1; + if (akey->Line > aelem->Line) return 1; + return 0; + } + if (l1 < l2) return 1; + if (l1 > l2) return -1; + } + return(char_key - char_elem); // akey->Key - aelem->Key); } DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) { - PFILE_GROUP gp; + PFILE_GROUP gp; - if(fk->currentGroup == 0xFFFFFFFF) return CERR_None; - // Just got to first group - so nothing to finish yet + if (fk->currentGroup == 0xFFFFFFFF) return CERR_None; + // Just got to first group - so nothing to finish yet - gp = &fk->dpGroupArray[fk->currentGroup]; + gp = &fk->dpGroupArray[fk->currentGroup]; - // Finish off the previous group stuff! - qsort(gp->dpKeyArray, gp->cxKeyArray, sizeof(FILE_KEY), cmpkeys); + // Finish off the previous group stuff! + qsort(gp->dpKeyArray, gp->cxKeyArray, sizeof(FILE_KEY), cmpkeys); - return CERR_None; - } + return CERR_None; +} /*************************************** * Store management @@ -987,35 +990,35 @@ DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PWSTR p) { - PWSTR q, pp; - PFILE_STORE sp; - //WCHAR temp[GLOBAL_BUFSIZE]; - DWORD msg; - int i = 0; + PWSTR q, pp; + PFILE_STORE sp; + //WCHAR temp[GLOBAL_BUFSIZE]; + DWORD msg; + int i = 0; - pp = p; + pp = p; - if((q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL)) == NULL) return CERR_InvalidStoreLine; + if ((q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL)) == NULL) return CERR_InvalidStoreLine; - if(*q == *SSN__PREFIX) - { - for(i = 0; StoreTokens[i]; i++) - if(!_wcsicmp(q, StoreTokens[i])) // I3481 - break; - if(!StoreTokens[i]) return CERR_InvalidSystemStore; - } + if (*q == *SSN__PREFIX) + { + for (i = 0; StoreTokens[i]; i++) + if (!_wcsicmp(q, StoreTokens[i])) // I3481 + break; + if (!StoreTokens[i]) return CERR_InvalidSystemStore; + } - sp = new FILE_STORE[fk->cxStoreArray+1]; - if(!sp) return CERR_CannotAllocateMemory; + 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; - } + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete fk->dpStoreArray; + } - fk->dpStoreArray = sp; - sp = &fk->dpStoreArray[fk->cxStoreArray]; + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; sp->line = currentLine; sp->fIsOption = FALSE; @@ -1028,58 +1031,58 @@ DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PWSTR p) { PWCHAR temp = new WCHAR[GLOBAL_BUFSIZE]; - if((msg = GetXString(fk, p, L"c\n", temp, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(p-pp), &p, FALSE, TRUE)) != CERR_None) - { - delete temp; - return msg; - } + if ((msg = GetXString(fk, p, L"c\n", temp, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(p - pp), &p, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } - sp->dwSystemID = i; - sp->dpString = new WCHAR[wcslen(temp)+1]; - wcscpy_s(sp->dpString, wcslen(temp)+1, temp); // I3481 + sp->dwSystemID = i; + sp->dpString = new WCHAR[wcslen(temp) + 1]; + wcscpy_s(sp->dpString, wcslen(temp) + 1, temp); // I3481 - delete temp; - } + delete[] temp; + } - if(xstrlen(sp->dpString) == 1 && *sp->dpString != UC_SENTINEL && - sp->dwSystemID == 0 && (fk->version >= VERSION_60 || fk->version == 0)) - { + 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 - char *codename = wstrtostr(sp->szName); - if(Uni_IsSurrogate1(*sp->dpString)) + // Add a single char store as a defined character constant + char *codename = wstrtostr(sp->szName); + if (Uni_IsSurrogate1(*sp->dpString)) CodeConstants->AddCode(Uni_SurrogateToUTF32(sp->dpString[0], sp->dpString[1]), codename, fk->cxStoreArray); - else - CodeConstants->AddCode(sp->dpString[0], codename, fk->cxStoreArray); - delete codename; + else + CodeConstants->AddCode(sp->dpString[0], codename, fk->cxStoreArray); + delete[] codename; 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 + fk->cxStoreArray++; // increment now, because GetXString refers to stores - if(i > 0) - if((msg = ProcessSystemStore(fk, i, sp)) != CERR_None) return msg; + if (i > 0) + if ((msg = ProcessSystemStore(fk, i, sp)) != CERR_None) return msg; - return CERR_None; + return CERR_None; } DWORD AddStore(PFILE_KEYBOARD fk, DWORD SystemID, PWSTR str, DWORD *dwStoreID) { - PFILE_STORE sp; + PFILE_STORE sp; - sp = new FILE_STORE[fk->cxStoreArray+1]; - if(!sp) return CERR_CannotAllocateMemory; + 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; - } + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete fk->dpStoreArray; + } - fk->dpStoreArray = sp; - sp = &fk->dpStoreArray[fk->cxStoreArray]; + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; sp->line = currentLine; sp->fIsOption = FALSE; // I3686 @@ -1088,211 +1091,211 @@ DWORD AddStore(PFILE_KEYBOARD fk, DWORD SystemID, PWSTR str, DWORD *dwStoreID) sp->fIsDebug = FALSE; sp->fIsCall = FALSE; - safe_wcsncpy(sp->szName, StoreTokens[SystemID], SZMAX_STORENAME); + safe_wcsncpy(sp->szName, StoreTokens[SystemID], SZMAX_STORENAME); - sp->dpString = new WCHAR[wcslen(str)+1]; - wcscpy_s(sp->dpString, wcslen(str)+1, str); // I3481 + sp->dpString = new WCHAR[wcslen(str) + 1]; + wcscpy_s(sp->dpString, wcslen(str) + 1, str); // I3481 - sp->dwSystemID = SystemID; + sp->dwSystemID = SystemID; - if(dwStoreID) *dwStoreID = fk->cxStoreArray; + if (dwStoreID) *dwStoreID = fk->cxStoreArray; fk->cxStoreArray++; - return ProcessSystemStore(fk, SystemID, sp); + return ProcessSystemStore(fk, SystemID, sp); } DWORD AddDebugStore(PFILE_KEYBOARD fk, PWSTR str) { - PFILE_STORE sp; - WCHAR tstr[16]; + PFILE_STORE sp; + WCHAR tstr[16]; - swprintf(tstr, _countof(tstr), L"%d", currentLine); // I3481 + swprintf(tstr, _countof(tstr), L"%d", currentLine); // I3481 - sp = new FILE_STORE[fk->cxStoreArray+1]; - if(!sp) return CERR_CannotAllocateMemory; + 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; - } + if (fk->dpStoreArray) + { + memcpy(sp, fk->dpStoreArray, sizeof(FILE_STORE) * fk->cxStoreArray); + delete[] fk->dpStoreArray; + } - fk->dpStoreArray = sp; - sp = &fk->dpStoreArray[fk->cxStoreArray]; + fk->dpStoreArray = sp; + sp = &fk->dpStoreArray[fk->cxStoreArray]; - safe_wcsncpy(sp->szName, str, SZMAX_STORENAME); + safe_wcsncpy(sp->szName, str, SZMAX_STORENAME); - sp->dpString = new WCHAR[wcslen(tstr)+1]; - wcscpy_s(sp->dpString, wcslen(tstr)+1, tstr); // I3481 + sp->dpString = new WCHAR[wcslen(tstr) + 1]; + wcscpy_s(sp->dpString, wcslen(tstr) + 1, tstr); // 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++; + sp->dwSystemID = TSS_DEBUG_LINE; + fk->cxStoreArray++; - return CERR_None; + return CERR_None; } PWCHAR pssBuf = NULL; DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) { - //WCHAR buf[GLOBAL_BUFSIZE]; - int i, j; - DWORD msg; - PWSTR p, q; - char *pp; + //WCHAR buf[GLOBAL_BUFSIZE]; + int i, j; + DWORD msg; + PWSTR p, q; + char *pp; - if(!pssBuf) pssBuf = new WCHAR[GLOBAL_BUFSIZE]; - PWCHAR buf = pssBuf; + if (!pssBuf) pssBuf = new WCHAR[GLOBAL_BUFSIZE]; + PWCHAR buf = pssBuf; - switch(SystemID) - { - case TSS_BITMAP: - if((msg = ImportBitmapFile(fk, sp->dpString, &fk->dwBitmapSize, &fk->lpBitmap)) != CERR_None) - return msg; - break; + 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: + break; - case TSS_CALLDEFINITION_LOADFAILED: - break; + case TSS_CALLDEFINITION_LOADFAILED: + break; - case TSS_CAPSALWAYSOFF: - if(*sp->dpString == L'1') fk->dwFlags |= KF_CAPSALWAYSOFF; - break; + case TSS_CAPSALWAYSOFF: + if (*sp->dpString == L'1') fk->dwFlags |= KF_CAPSALWAYSOFF; + break; - case TSS_CAPSONONLY: - if(*sp->dpString == L'1') fk->dwFlags |= KF_CAPSONONLY; - break; + case TSS_CAPSONONLY: + if (*sp->dpString == L'1') fk->dwFlags |= KF_CAPSONONLY; + break; - case TSS_COMPILEDVERSION: - break; + case TSS_COMPILEDVERSION: + break; - case TSS_COPYRIGHT: - break; + case TSS_COPYRIGHT: + break; - case TSS_DEBUG_LINE: - break; + case TSS_DEBUG_LINE: + break; - case TSS_ETHNOLOGUECODE: + case TSS_ETHNOLOGUECODE: VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_EthnologueCode); - if((msg = ProcessEthnologueStore(sp->dpString)) != CERR_None) return msg; // I2646 - break; + 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; + case TSS_HOTKEY: + if ((msg = ProcessHotKey(sp->dpString, &fk->dwHotKey)) != CERR_None) return msg; - swprintf(buf, GLOBAL_BUFSIZE, L"%d", fk->dwHotKey); // I3481 - delete sp->dpString; - sp->dpString = new WCHAR[wcslen(buf)+1]; - wcscpy_s(sp->dpString, wcslen(buf)+1, buf); // I3481 - break; + swprintf(buf, GLOBAL_BUFSIZE, L"%d", (int)fk->dwHotKey); // I3481 + delete[] sp->dpString; + sp->dpString = new WCHAR[wcslen(buf) + 1]; + wcscpy_s(sp->dpString, wcslen(buf) + 1, buf); // I3481 + break; - case TSS_INCLUDECODES: - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); - pp = wstrtostr(sp->dpString); - if(!CodeConstants->LoadFile(pp)) - { - delete pp; - return CERR_CannotLoadIncludeFile; - } - delete pp; - CodeConstants->reindex(); // I4982 - break; - - case TSS_LANGUAGE: + case TSS_INCLUDECODES: + VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); + pp = wstrtostr(sp->dpString); + if (!CodeConstants->LoadFile(pp)) { - wchar_t *context = NULL; - q = wcstok_s(sp->dpString, L", ", &context); // I3481 - if(!q) return CERR_InvalidLanguageLine; - - i = xatoi(&q); - q = wcstok_s(NULL, L" c\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 = (DWORD) MAKELANGID(i, j); - - swprintf(buf, GLOBAL_BUFSIZE, L"%x %x", i, j); // I3481 - delete sp->dpString; - sp->dpString = new WCHAR[wcslen(buf)+1]; - wcscpy_s(sp->dpString, wcslen(buf)+1, buf); // I3481 - - break; + delete[] pp; + return CERR_CannotLoadIncludeFile; } - case TSS_LANGUAGENAME: - break; + delete[] pp; + CodeConstants->reindex(); // I4982 + break; - case TSS_LAYOUT: - if(fk->KeyboardID == 0) return CERR_LayoutButNoLanguage; + case TSS_LANGUAGE: + { + wchar_t *context = NULL; + q = wcstok_s(sp->dpString, L", ", &context); // I3481 + if (!q) return CERR_InvalidLanguageLine; - q = sp->dpString; + i = xatoi(&q); + q = wcstok_s(NULL, L" c\n", &context); // I3481 + if (!q) + { + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_InvalidLanguageLine); + j = SUBLANGID(i); + i = PRIMARYLANGID(i); + } + else + j = xatoi(&q); - fk->KeyboardID |= (xatoi(&q) << 16L); - break; + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) return CERR_InvalidLanguageLine; + if (i >= 0x200 || j >= 0x20) AddWarning(CWARN_CustomLanguagesNotSupported); - case TSS_MESSAGE: - break; + fk->KeyboardID = (DWORD)MAKELANGID(i, j); - case TSS_MNEMONIC: + swprintf(buf, GLOBAL_BUFSIZE, L"%x %x", i, j); // I3481 + delete[] sp->dpString; + sp->dpString = new WCHAR[wcslen(buf) + 1]; + wcscpy_s(sp->dpString, wcslen(buf) + 1, buf); // 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); - FMnemonicLayout = atoiW(sp->dpString) == 1; - break; + FMnemonicLayout = atoiW(sp->dpString) == 1; + break; - case TSS_NAME: - break; + case TSS_NAME: + break; - case TSS_OLDCHARPOSMATCHING: + case TSS_OLDCHARPOSMATCHING: VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_OldCharPosMatching); - FOldCharPosMatching = atoiW(sp->dpString); - break; + FOldCharPosMatching = atoiW(sp->dpString); + break; - case TSS_SHIFTFREESCAPS: - if(*sp->dpString == L'1') fk->dwFlags |= KF_SHIFTFREESCAPS; - break; + case TSS_SHIFTFREESCAPS: + if (*sp->dpString == L'1') fk->dwFlags |= KF_SHIFTFREESCAPS; + break; - case TSS_VERSION: - if((fk->dwFlags & KF_AUTOMATICVERSION) == 0) return CERR_VersionAlreadyIncluded; - p = sp->dpString; + case TSS_VERSION: + if ((fk->dwFlags & KF_AUTOMATICVERSION) == 0) return CERR_VersionAlreadyIncluded; + p = sp->dpString; if (wcstof(p, NULL) < 5.0) { AddWarning(CWARN_OldVersion); } - if(wcsncmp(p, L"3.0", 3) == 0) fk->version = VERSION_50; //0x0a0b000n= a.bn - else if(wcsncmp(p, L"3.1", 3) == 0) fk->version = VERSION_50; //all versions < 5.0 - else if(wcsncmp(p, L"3.2", 3) == 0) fk->version = VERSION_50; //we compile as if - else if(wcsncmp(p, L"4.0", 3) == 0) fk->version = VERSION_50; //they are 5.0.100.0 - else if(wcsncmp(p, L"5.01", 4) == 0) fk->version = VERSION_501; - else if(wcsncmp(p, L"5.0", 3) == 0) fk->version = VERSION_50; - else if(wcsncmp(p, L"6.0", 3) == 0) fk->version = VERSION_60; - else if(wcsncmp(p, L"7.0", 3) == 0) fk->version = VERSION_70; - else if(wcsncmp(p, L"8.0", 3) == 0) fk->version = VERSION_80; - else if(wcsncmp(p, L"9.0", 3) == 0) fk->version = VERSION_90; + if (wcsncmp(p, L"3.0", 3) == 0) fk->version = VERSION_50; //0x0a0b000n= a.bn + else if (wcsncmp(p, L"3.1", 3) == 0) fk->version = VERSION_50; //all versions < 5.0 + else if (wcsncmp(p, L"3.2", 3) == 0) fk->version = VERSION_50; //we compile as if + else if (wcsncmp(p, L"4.0", 3) == 0) fk->version = VERSION_50; //they are 5.0.100.0 + else if (wcsncmp(p, L"5.01", 4) == 0) fk->version = VERSION_501; + else if (wcsncmp(p, L"5.0", 3) == 0) fk->version = VERSION_50; + else if (wcsncmp(p, L"6.0", 3) == 0) fk->version = VERSION_60; + else if (wcsncmp(p, L"7.0", 3) == 0) fk->version = VERSION_70; + else if (wcsncmp(p, L"8.0", 3) == 0) fk->version = VERSION_80; + else if (wcsncmp(p, L"9.0", 3) == 0) fk->version = VERSION_90; else if (wcsncmp(p, L"10.0", 4) == 0) fk->version = VERSION_100; else return CERR_InvalidVersion; - if(fk->version < VERSION_60) FOldCharPosMatching = TRUE; + if (fk->version < VERSION_60) FOldCharPosMatching = TRUE; fk->dwFlags &= ~KF_AUTOMATICVERSION; - break; + break; - case TSS_VISUALKEYBOARD: + case TSS_VISUALKEYBOARD: VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); { // Strip path from the store, leaving bare filename only @@ -1304,7 +1307,7 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) pp++; } q = new WCHAR[wcslen(pp) + 1]; - wcscpy_s(q, wcslen(pp)+1, pp); + wcscpy_s(q, wcslen(pp) + 1, pp); // Change compiled reference file extension to .kvk pp = wcschr(q, 0) - 5; @@ -1312,14 +1315,14 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) pp[4] = 0; } - delete sp->dpString; + delete[] sp->dpString; sp->dpString = q; } break; - case TSS_KMW_RTL: - case TSS_KMW_HELPFILE: - case TSS_KMW_HELPTEXT: - case TSS_KMW_EMBEDJS: + case TSS_KMW_RTL: + case TSS_KMW_HELPFILE: + case TSS_KMW_HELPTEXT: + case TSS_KMW_EMBEDJS: VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); break; @@ -1332,32 +1335,35 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) break; case TSS_WINDOWSLANGUAGES: + { + wchar_t *context = NULL; + VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + size_t szQ = wcslen(sp->dpString) * 6 + 1; // I3481 + q = new WCHAR[szQ]; // guaranteed to be enough space for recoding + *q = 0; WCHAR *r = q; + p = wcstok_s(sp->dpString, L" ", &context); // I3481 + while (p) { - wchar_t *context = NULL; - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); - size_t szQ = wcslen(sp->dpString) * 6 + 1; // I3481 - q = new WCHAR[szQ]; // guaranteed to be enough space for recoding - *q = 0; WCHAR *r = q; - p = wcstok_s(sp->dpString, L" ", &context); // I3481 - while(p) - { - int n = xatoi(&p); + int n = xatoi(&p); - j = SUBLANGID(n); - i = PRIMARYLANGID(n); + j = SUBLANGID(n); + i = PRIMARYLANGID(n); - if(i < 1 || j < 1 || i > 0x3FF || j > 0x3F) return CERR_InvalidLanguageLine; - - swprintf(r, szQ - (size_t)(r-q), L"x%04.4x ", n); // I3481 - - p = wcstok_s(NULL, L" ", &context); // I3481 - r = wcschr(q, 0); // I3481 + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) { + delete[] q; + return CERR_InvalidLanguageLine; } - delete sp->dpString; - if(*q) *(wcschr(q, 0)-1) = 0; // delete final space - safe because we control the formatting - ugly? scared? - sp->dpString = q; - break; + + swprintf(r, szQ - (size_t)(r - q), L"x%04.4x ", n); // I3481 + + p = wcstok_s(NULL, L" ", &context); // I3481 + r = wcschr(q, 0); // I3481 } + delete[] sp->dpString; + if (*q) *(wcschr(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; @@ -1373,76 +1379,76 @@ DWORD ProcessSystemStore(PFILE_KEYBOARD fk, DWORD SystemID, PFILE_STORE sp) case TSS_KEYBOARDVERSION: // I4140 VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyKeyboardVersion); - if(!IsValidKeyboardVersion(sp->dpString)) { + if (!IsValidKeyboardVersion(sp->dpString)) { return CERR_KeyboardVersionFormatInvalid; } break; - default: - return CERR_InvalidSystemStore; - } - return CERR_None; + default: + return CERR_InvalidSystemStore; + } + return CERR_None; } BOOL IsValidKeyboardVersion(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)) { + if (!iswdigit(*dpString)) { return FALSE; } - while(iswdigit(*dpString)) { + while (iswdigit(*dpString)) { dpString++; } - if(*dpString == '.') { + if (*dpString == '.') { dpString++; - if(!iswdigit(*dpString)) { + if (!iswdigit(*dpString)) { return FALSE; } } - } while(*dpString != 0); + } while (*dpString != 0); return TRUE; } BOOL GetFileVersion(char *filename, WORD *d1, WORD *d2, WORD *d3, WORD *d4) { - char fnbuf[260]; - DWORD h; - DWORD sz; - PSTR p; - VS_FIXEDFILEINFO *vffi; - UINT len; + char fnbuf[260]; + DWORD h; + DWORD sz; + PSTR p; + VS_FIXEDFILEINFO *vffi; + UINT len; - GetModuleFileName(0, fnbuf, 260); - sz = GetFileVersionInfoSize(fnbuf, &h); - if(sz == 0) return FALSE; - p = new char[sz]; - if(!p) return FALSE; - GetFileVersionInfo(fnbuf, h, sz, p); - VerQueryValue(p, "\\", (void **) &vffi, &len); + GetModuleFileName(0, fnbuf, 260); + sz = GetFileVersionInfoSize(fnbuf, &h); + if (sz == 0) return FALSE; + p = new char[sz]; + if (!p) return FALSE; + GetFileVersionInfo(fnbuf, h, sz, p); + VerQueryValue(p, "\\", (void **)&vffi, &len); - *d1 = HIWORD(vffi->dwFileVersionMS); - *d2 = LOWORD(vffi->dwFileVersionMS); - *d3 = HIWORD(vffi->dwFileVersionLS); - *d4 = LOWORD(vffi->dwFileVersionLS); + *d1 = HIWORD(vffi->dwFileVersionMS); + *d2 = LOWORD(vffi->dwFileVersionMS); + *d3 = HIWORD(vffi->dwFileVersionLS); + *d4 = LOWORD(vffi->dwFileVersionLS); - delete p; - return TRUE; + delete[] p; + return TRUE; } DWORD AddCompilerVersionStore(PFILE_KEYBOARD fk) { - WCHAR verstr[32]; - WORD d1, d2, d3, d4; - DWORD msg; + WCHAR verstr[32]; + WORD d1, d2, d3, d4; + DWORD msg; - GetFileVersion(NULL, &d1, &d2, &d3, &d4); - swprintf(verstr, _countof(verstr), L"%d.%d.%d.%d", d1, d2, d3, d4); // I3481 + GetFileVersion(NULL, &d1, &d2, &d3, &d4); + swprintf(verstr, _countof(verstr), L"%d.%d.%d.%d", d1, d2, d3, d4); // I3481 - if((msg = AddStore(fk, TSS_COMPILEDVERSION, verstr)) != CERR_None) return msg; + if ((msg = AddStore(fk, TSS_COMPILEDVERSION, verstr)) != CERR_None) return msg; - return CERR_None; + return CERR_None; } /**************************** @@ -1452,38 +1458,39 @@ DWORD AddCompilerVersionStore(PFILE_KEYBOARD fk) DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PWSTR context, PWSTR output, PWSTR key) { PWSTR 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++); + 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) + 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 + if (i < contextOffset) // I4914 // offset is beyond the key return CERR_IndexDoesNotPointToAny; - q = key; - } + q = key; + } - // find the any - if(*q != UC_SENTINEL || *(q+1) != CODE_ANY) + // find the any + if (*q != UC_SENTINEL || *(q + 1) != CODE_ANY) return CERR_IndexDoesNotPointToAny; - int anyStore = *(q+2) - 1; + int anyStore = *(q + 2) - 1; - if(xstrlen(fk->dpStoreArray[indexStore].dpString) < xstrlen(fk->dpStoreArray[anyStore].dpString)) - AddWarning(CWARN_IndexStoreShort); - } else if(*(p+1) == CODE_CONTEXTEX) { - int contextOffset = *(p+2); - if(contextOffset > xstrlen(context)) + if (xstrlen(fk->dpStoreArray[indexStore].dpString) < xstrlen(fk->dpStoreArray[anyStore].dpString)) { + AddWarning(CWARN_IndexStoreShort); + } + } else if (*(p + 1) == CODE_CONTEXTEX) { + int contextOffset = *(p + 2); + if (contextOffset > xstrlen(context)) return CERR_ContextExHasInvalidOffset; } } - } + } return CERR_None; } @@ -1493,10 +1500,10 @@ DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PWSTR context, PW DWORD CheckUseStatementsInOutput(PWSTR output) { // I4867 BOOL HasUse = FALSE; PWSTR p; - for(p = output; *p; p = incxstr(p)) { - if(*p == UC_SENTINEL && *(p+1) == CODE_USE) { + for (p = output; *p; p = incxstr(p)) { + if (*p == UC_SENTINEL && *(p + 1) == CODE_USE) { HasUse = TRUE; - } else if(HasUse) { + } else if (HasUse) { AddWarning(CWARN_UseNotLastStatementInRule); return FALSE; } @@ -1506,101 +1513,101 @@ DWORD CheckUseStatementsInOutput(PWSTR output) { // I4867 DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PWSTR str, BOOL IsUnicode) { - PWSTR p, pp; - DWORD msg; - PFILE_GROUP gp; - PFILE_KEY kp; + PWSTR p, pp; + DWORD msg; + PFILE_GROUP gp; + PFILE_KEY kp; PWCHAR pklIn, pklKey, pklOut; - pklIn = new WCHAR[GLOBAL_BUFSIZE]; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer - pklKey = new WCHAR[GLOBAL_BUFSIZE]; - pklOut = new WCHAR[GLOBAL_BUFSIZE]; - if(!pklIn|| !pklKey || !pklOut) + pklIn = new WCHAR[GLOBAL_BUFSIZE]; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer + pklKey = new WCHAR[GLOBAL_BUFSIZE]; + pklOut = new WCHAR[GLOBAL_BUFSIZE]; + if (!pklIn || !pklKey || !pklOut) return CERR_CannotAllocateMemory; // forget about the little leak if pklKey or pklOut fail... __try { - gp = &fk->dpGroupArray[fk->currentGroup]; + gp = &fk->dpGroupArray[fk->currentGroup]; - pp = str; + pp = str; - if(gp->fUsingKeys) { - if((msg = GetXString(fk, str, L"+", pklIn, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(str-pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if (gp->fUsingKeys) { + if ((msg = GetXString(fk, str, L"+", pklIn, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - str = p + 1; - if((msg = GetXString(fk, str, L">", pklKey, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(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, L">", pklIn, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(str-pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - if(pklIn[0] == 0) return CERR_ZeroLengthString; - } + str = p + 1; + if ((msg = GetXString(fk, str, L">", pklKey, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(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, L">", pklIn, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if (pklIn[0] == 0) return CERR_ZeroLengthString; + } - str = p + 1; - if((msg = GetXString(fk, str, L"c\n", pklOut, GLOBAL_BUFSIZE-1, (int)(INT_PTR)(str-pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + str = p + 1; + if ((msg = GetXString(fk, str, L"c\n", pklOut, GLOBAL_BUFSIZE - 1, (int)(INT_PTR)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - if(pklOut[0] == 0) return CERR_ZeroLengthString; + if (pklOut[0] == 0) return CERR_ZeroLengthString; // Test index and context offsets in context - if((msg = CheckStatementOffsets(fk, gp, pklIn, pklOut, pklKey)) != CERR_None) return msg; + if ((msg = CheckStatementOffsets(fk, gp, pklIn, pklOut, pklKey)) != CERR_None) return msg; // Test that use() statements are not followed by other content CheckUseStatementsInOutput(pklOut); // I4867 - kp = new FILE_KEY[gp->cxKeyArray + 1]; - if(!kp) return CERR_CannotAllocateMemory; - if(gp->dpKeyArray) + 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 WCHAR[wcslen(pklOut) + 1]; + wcscpy_s(kp->dpOutput, wcslen(pklOut) + 1, pklOut); // I3481 + + kp->dpContext = new WCHAR[wcslen(pklIn) + 1]; + wcscpy_s(kp->dpContext, wcslen(pklIn) + 1, pklIn); // I3481 + + kp->Line = currentLine; + + // 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)) { - 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 WCHAR[wcslen(pklOut)+1]; - wcscpy_s(kp->dpOutput, wcslen(pklOut)+1, pklOut); // I3481 - - kp->dpContext = new WCHAR[wcslen(pklIn)+1]; - wcscpy_s(kp->dpContext, wcslen(pklIn)+1, pklIn); // I3481 - - kp->Line = currentLine; - - // 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_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; + kp->Key = *(pklKey + 3); + kp->ShiftFlags = *(pklKey + 2); + break; default: - return CERR_InvalidCodeInKeyPartOfRule; - } + return CERR_InvalidCodeInKeyPartOfRule; + } else { - kp->ShiftFlags = 0; - kp->Key = *pklKey; + kp->ShiftFlags = 0; + kp->Key = *pklKey; } } @@ -1611,150 +1618,150 @@ DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PWSTR str, BOOL IsUnicode) delete pklOut; } - return CERR_None; + return CERR_None; } DWORD ExpandKp_ReplaceIndex(PFILE_KEYBOARD fk, PFILE_KEY k, DWORD keyIndex, int nAnyIndex) { - /* Replace each index(xx,keyIndex) in k->dpOutput with appropriate char as based on nAnyIndex */ - PFILE_STORE s; - int i; - PWSTR pIndex, pStore; + /* Replace each index(xx,keyIndex) in k->dpOutput with appropriate char as based on nAnyIndex */ + PFILE_STORE s; + int i; + PWSTR pIndex, pStore; - for(pIndex = k->dpOutput; *pIndex; pIndex = incxstr(pIndex)) + for (pIndex = k->dpOutput; *pIndex; pIndex = incxstr(pIndex)) + { + if (*pIndex == UC_SENTINEL && *(pIndex + 1) == CODE_INDEX && *(pIndex + 3) == keyIndex) { - 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)); - PWSTR qStore = incxstr(pStore); + s = &fk->dpStoreArray[*(pIndex + 2) - 1]; + for (i = 0, pStore = s->dpString; i < nAnyIndex; i++, pStore = incxstr(pStore)); + PWSTR qStore = incxstr(pStore); - int w = (int)(INT_PTR)(qStore - pStore); - if(w > 4) - { - *pIndex = UC_SENTINEL; - *(pIndex+1) = CODE_BEEP; - memmove(pIndex+2, pIndex+4, wcslen(pIndex+3)*2); - } - else - { - memcpy(pIndex, pStore, w*2); - if(w < 4) memmove(pIndex+w, pIndex+4, wcslen(pIndex+3)*2); - } - } - } + int w = (int)(INT_PTR)(qStore - pStore); + if (w > 4) + { + *pIndex = UC_SENTINEL; + *(pIndex + 1) = CODE_BEEP; + memmove(pIndex + 2, pIndex + 4, wcslen(pIndex + 3) * 2); + } + else + { + memcpy(pIndex, pStore, w * 2); + if (w < 4) memmove(pIndex + w, pIndex + 4, wcslen(pIndex + 3) * 2); + } + } + } - return CERR_None; + return CERR_None; } DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, DWORD storeIndex) { - PFILE_KEY k; - PWSTR pn; - DWORD nchrs, n; - int keyIndex; + PFILE_KEY k; + PWSTR pn; + DWORD nchrs, n; + int keyIndex; - PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; - PFILE_GROUP gp = &fk->dpGroupArray[fk->currentGroup]; + PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; + PFILE_GROUP gp = &fk->dpGroupArray[fk->currentGroup]; - PWSTR dpContext = kpp->dpContext; - PWSTR dpOutput = kpp->dpOutput; + PWSTR dpContext = kpp->dpContext; + PWSTR dpOutput = kpp->dpOutput; - nchrs = xstrlen(sp->dpString); - pn = sp->dpString; - keyIndex = xstrlen(dpContext) + 1; + 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. - */ + /* + 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)); + 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_PTR)(kpp - gp->dpKeyArray)]; + kpp = &k[(INT_PTR)(kpp - gp->dpKeyArray)]; - delete gp->dpKeyArray; - gp->dpKeyArray = k; - gp->cxKeyArray += nchrs - 1; + delete gp->dpKeyArray; + gp->dpKeyArray = k; + gp->cxKeyArray += nchrs - 1; - for(k = kpp, n = 0, pn = sp->dpString; *pn; pn=incxstr(pn), k++, n++) + for (k = kpp, n = 0, pn = sp->dpString; *pn; pn = incxstr(pn), k++, n++) + { + k->dpContext = new WCHAR[wcslen(dpContext) + 1]; + k->dpOutput = new WCHAR[wcslen(dpOutput) + 1]; + + wcscpy_s(k->dpContext, wcslen(dpContext) + 1, dpContext); // copy the context. // I3481 + wcscpy_s(k->dpOutput, wcslen(dpOutput) + 1, dpOutput); // copy the output. + + if (*pn == UC_SENTINEL) { - k->dpContext = new WCHAR[wcslen(dpContext) + 1]; - k->dpOutput = new WCHAR[wcslen(dpOutput) + 1]; + 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; + ExpandKp_ReplaceIndex(fk, k, keyIndex, n); + } - wcscpy_s(k->dpContext, wcslen(dpContext)+1, dpContext); // copy the context. // I3481 - wcscpy_s(k->dpOutput, wcslen(dpOutput)+1, dpOutput); // copy the output. + delete dpContext; + delete dpOutput; - 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; - ExpandKp_ReplaceIndex(fk, k, keyIndex, n); - } - - delete dpContext; - delete dpOutput; - - return CERR_None; + return CERR_None; } PWSTR GetDelimitedString(PWSTR *p, PWSTR Delimiters, WORD Flags) { - PWSTR q, r; - WCHAR dOpen, dClose; + PWSTR q, r; + WCHAR dOpen, dClose; - dOpen = *Delimiters; dClose = *(Delimiters+1); + dOpen = *Delimiters; dClose = *(Delimiters + 1); - q = *p; - while(iswspace(*q)) q++; //***QUERY + q = *p; + while (iswspace(*q)) q++; //***QUERY - if(*q != dOpen) return NULL; + if (*q != dOpen) return NULL; - q++; + q++; - r = wcschr(q, dClose); // Find closing delimiter - if(!r) return NULL; + r = wcschr(q, dClose); // Find closing delimiter + if (!r) return NULL; - if(Flags & GDS_CUTLEAD) - while(iswspace(*q)) q++; // cut off leading spaces + 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 = wcschr((r + 1), dClose); - } - else *r = 0; + 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 = wcschr((r + 1), dClose); + } + else *r = 0; - r++; while(iswspace(*r)) r++; // Ignore spaces after the close - if(*r == 0) r--; // Safety for terminating strings. + r++; while (iswspace(*r)) r++; // Ignore spaces after the close + if (*r == 0) r--; // Safety for terminating strings. - *p = r; // Update pointer position + *p = r; // Update pointer position - return q; // Return delimited string + return q; // Return delimited string } @@ -1762,30 +1769,30 @@ enum LinePrefixType { lptNone, lptKeymanAndKeymanWeb, lptKeymanWebOnly, lptKeyma LinePrefixType GetLinePrefixType(PWSTR *p) { - PWSTR s = *p; + PWSTR s = *p; - while(iswspace(*s)) s++; + while (iswspace(*s)) s++; PWSTR q = s; - if(*s != '$') return lptNone; + if (*s != '$') return lptNone; /* I1569 - fix named constants at the start of the line */ s++; - while(__iswcsym(*s)) s++; - if(*s != ':') return lptNone; + while (__iswcsym(*s)) s++; + if (*s != ':') return lptNone; - if(_wcsnicmp(q, L"$keyman:", 8) == 0) + if (_wcsnicmp(q, L"$keyman:", 8) == 0) { - *p += 8; + *p += 8; return lptKeymanAndKeymanWeb; - } - if(_wcsnicmp(q, L"$keymanweb:", 11) == 0) + } + if (_wcsnicmp(q, L"$keymanweb:", 11) == 0) { *p += 11; return lptKeymanWebOnly; } - if(_wcsnicmp(q, L"$keymanonly:", 12) == 0) + if (_wcsnicmp(q, L"$keymanonly:", 12) == 0) { *p += 12; return lptKeymanOnly; @@ -1798,64 +1805,64 @@ int LineTokenType(PWSTR *str) { int i; size_t l; - PWSTR p = *str; + PWSTR p = *str; LinePrefixType lpt = GetLinePrefixType(&p); - if(lpt == lptOther) return T_BLANK; + if (lpt == lptOther) return T_BLANK; /* Test KeymanWeb, Keyman and KeymanOnly prefixes */ - if(CompileTarget == CKF_KEYMAN && lpt == lptKeymanWebOnly) return T_BLANK; - if(CompileTarget == CKF_KEYMANWEB && lpt == lptKeymanOnly) return T_BLANK; + if (CompileTarget == CKF_KEYMAN && lpt == lptKeymanWebOnly) return T_BLANK; + if (CompileTarget == CKF_KEYMANWEB && lpt == lptKeymanOnly) return T_BLANK; - while(iswspace(*p)) p++; + while (iswspace(*p)) p++; - if(wcschr(LineTokens[0], towupper(*p))) - for(i = 0; i <= T_W_END - T_W_START; i++) - { - l = wcslen(LineTokens[i+1]); - if(_wcsnicmp(p, LineTokens[i+1], l) == 0) - { - p += l; while(iswspace(*p)) p++; *str = p; - return i + T_W_START; - } - } - - switch(towupper(*p)) + if (wcschr(LineTokens[0], towupper(*p))) + for (i = 0; i <= T_W_END - T_W_START; i++) { - case 'C': - if(iswspace(*(p+1))) return T_COMMENT; - break; - case 0: - return T_BLANK; - default: - if(wcschr(L"\"aAbBlLpPnN[OoxXdD0123456789\'+UuiI$", *p)) // I4784 - { - *str = p; - return T_KEYTOKEY; - } - } - return T_UNKNOWN; + l = wcslen(LineTokens[i + 1]); + if (_wcsnicmp(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 (wcschr(L"\"aAbBlLpPnN[OoxXdD0123456789\'+UuiI$", *p)) // I4784 + { + *str = p; + return T_KEYTOKEY; + } + } + return T_UNKNOWN; } const PWSTR DeadKeyChars = - L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; +L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; BOOL strvalidchrs(PWSTR q, PWSTR chrs) { - for(; *q; q++) - if(!wcschr(chrs, *q)) return FALSE; - return TRUE; + for (; *q; q++) + if (!wcschr(chrs, *q)) return FALSE; + return TRUE; } DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int max, int offset, PWSTR *newp, int isVKey, int isUnicode) { - DWORD err; - PWSTR p = str, q, r; - int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, sFlag = 0, j; - DWORD i; - BOOL finished = FALSE; - WCHAR c; - PSTR codename; + DWORD err; + PWSTR p = str, q, r; + int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, sFlag = 0, j; + DWORD i; + BOOL finished = FALSE; + WCHAR c; + PSTR codename; PWCHAR tstr = NULL; int tstrMax = 0; @@ -1867,406 +1874,406 @@ DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int ma { *tstr = 0; - *output = 0; + *output = 0; - p = str; - do + p = str; + do + { + tokenFound = FALSE; + while (iswspace(*p) && !wcschr(token, *p)) p++; + if (!*p) break; + + ErrChr = (int)(INT_PTR)(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)) { - tokenFound = FALSE; - while(iswspace(*p) && !wcschr(token, *p)) p++; - if(!*p) break; - - ErrChr = (int)(INT_PTR)(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 - default: - if(iswdigit(*p)) type = 0; // octal number - else type = 99; // error! + 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 + default: + if (iswdigit(*p)) type = 0; // octal number + else type = 99; // error! } - if(wcschr(token, *p)) tokenFound = TRUE; + if (wcschr(token, *p)) tokenFound = TRUE; - switch(type) - { - case 99: - if(tokenFound) break; - wsprintf(ErrExtra, "token: %c", (int) *p); - return CERR_InvalidToken; - case 0: - if(_wcsnicmp(p, L"deadkey", z = 7) == 0 || - _wcsnicmp(p, L"dk", z = 2) == 0 ) + switch (type) + { + case 99: + if (tokenFound) break; + wsprintf(ErrExtra, "token: %c", (int)*p); + return CERR_InvalidToken; + case 0: + if (_wcsnicmp(p, L"deadkey", z = 7) == 0 || + _wcsnicmp(p, L"dk", z = 2) == 0) { - p += z; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidDeadkey; + p += z; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidDeadkey; - DWORD n = fk->cxDeadKeyArray; + DWORD n = fk->cxDeadKeyArray; 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 + 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 = UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; - tstr[mx++] = n1; - if(n2 >= 0) tstr[mx++] = n2; - tstr[mx] = 0; - } - continue; - case 1: - q = wcschr(p+1, '\"'); - if(!q) return CERR_UnterminatedString; - if((INT_PTR)(q-p) - 1 + mx > max) return CERR_UnterminatedString; - if(sFlag) return CERR_StringInVirtualKeySection; - wcsncat_s(tstr, max, p+1, (INT_PTR)(q-p)-1); // I3481 - mx += (int)(INT_PTR)(q-p)-1; - tstr[mx] = 0; - p = q+1; - continue; - case 2: - q = wcschr(p+1, '\''); - if(!q) return CERR_UnterminatedString; - if((INT_PTR)(q-p) - 1 + mx > max) return CERR_UnterminatedString; - if(sFlag) return CERR_StringInVirtualKeySection; - wcsncat_s(tstr, max, p+1, (INT_PTR)(q-p)-1); // I3481 - mx += (int)(INT_PTR)(q-p)-1; - tstr[mx] = 0; - p = q+1; - continue; - case 3: - if(_wcsnicmp(p, L"any", 3) != 0) return CERR_InvalidToken; - if(sFlag) return CERR_AnyInVirtualKeySection; - p += 3; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidAny; + n = xatoi(&p); + if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; + if ((err = UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; + tstr[mx++] = n1; + if (n2 >= 0) tstr[mx++] = n2; + tstr[mx] = 0; + } + continue; + case 1: + q = wcschr(p + 1, '\"'); + if (!q) return CERR_UnterminatedString; + if ((INT_PTR)(q - p) - 1 + mx > max) return CERR_UnterminatedString; + if (sFlag) return CERR_StringInVirtualKeySection; + wcsncat_s(tstr, max, p + 1, (INT_PTR)(q - p) - 1); // I3481 + mx += (int)(INT_PTR)(q - p) - 1; + tstr[mx] = 0; + p = q + 1; + continue; + case 2: + q = wcschr(p + 1, '\''); + if (!q) return CERR_UnterminatedString; + if ((INT_PTR)(q - p) - 1 + mx > max) return CERR_UnterminatedString; + if (sFlag) return CERR_StringInVirtualKeySection; + wcsncat_s(tstr, max, p + 1, (INT_PTR)(q - p) - 1); // I3481 + mx += (int)(INT_PTR)(q - p) - 1; + tstr[mx] = 0; + p = q + 1; + continue; + case 3: + if (_wcsnicmp(p, L"any", 3) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_AnyInVirtualKeySection; + p += 3; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidAny; - for(i = 0; i < fk->cxStoreArray; i++) - { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + for (i = 0; i < fk->cxStoreArray; i++) + { + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; - if(!*fk->dpStoreArray[i].dpString) return CERR_ZeroLengthString; + if (!*fk->dpStoreArray[i].dpString) return CERR_ZeroLengthString; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_ANY; - tstr[mx++] = (WCHAR)i+1; // store to index + 1, avoids End-of-string - tstr[mx] = 0; - continue; - case 4: - if(_wcsnicmp(p, L"beep", 4) == 0) + tstr[mx++] = CODE_ANY; + tstr[mx++] = (WCHAR)i + 1; // store to index + 1, avoids End-of-string + tstr[mx] = 0; + continue; + case 4: + if (_wcsnicmp(p, L"beep", 4) == 0) { - if(sFlag) return CERR_BeepInVirtualKeySection; - p += 4; + if (sFlag) return CERR_BeepInVirtualKeySection; + p += 4; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_BEEP; - tstr[mx] = 0; + tstr[mx++] = CODE_BEEP; + tstr[mx] = 0; } - else if(_wcsnicmp(p, L"baselayout", 10) == 0) // I3430 + else if (_wcsnicmp(p, L"baselayout", 10) == 0) // I3430 { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); - if(sFlag) return CERR_InvalidInVirtualKeySection; - p += 10; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 10; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return CERR_InvalidToken; err = process_baselayout(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else return CERR_InvalidToken; - continue; - case 5: - if(_wcsnicmp( p, L"if", 2) == 0) + continue; + case 5: + if (_wcsnicmp(p, L"if", 2) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); - if(sFlag) return CERR_InvalidInVirtualKeySection; + if (sFlag) return CERR_InvalidInVirtualKeySection; p += 2; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidIf; + if (!q || !*q) return CERR_InvalidIf; err = process_if(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else { - if(_wcsnicmp( p, L"index", 5) != 0) return CERR_InvalidToken; - if(sFlag) return CERR_IndexInVirtualKeySection; - p += 5; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (_wcsnicmp(p, L"index", 5) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_IndexInVirtualKeySection; + p += 5; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidIndex; + if (!q || !*q) return CERR_InvalidIndex; { wchar_t *context = NULL; - r = wcstok_s(q, L" ,", &context); // I3481 - if(!r) return CERR_InvalidIndex; + r = wcstok_s(q, L" ,", &context); // I3481 + if (!r) return CERR_InvalidIndex; - for(i=0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); r = wcstok_s(NULL, L" ,", &context); // I3481 - if(!r) return CERR_InvalidIndex; + if (!r) return CERR_InvalidIndex; } tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_INDEX; - tstr[mx++] = (WCHAR)i+1; // avoid EOS for stores - tstr[mx++] = atoiW(r); // character offset of original any. + tstr[mx++] = CODE_INDEX; + tstr[mx++] = (WCHAR)i + 1; // avoid EOS for stores + tstr[mx++] = atoiW(r); // character offset of original any. - tstr[mx] = 0; + tstr[mx] = 0; } - continue; - case 6: - if(_wcsnicmp(p, L"outs", 4) != 0) return CERR_InvalidToken; - if(sFlag) return CERR_OutsInVirtualKeySection; - p += 4; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidOuts; + continue; + case 6: + if (_wcsnicmp(p, L"outs", 4) != 0) return CERR_InvalidToken; + if (sFlag) return CERR_OutsInVirtualKeySection; + p += 4; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidOuts; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); - for(q = fk->dpStoreArray[i].dpString; *q; q++) + 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(_wcsnicmp(p, L"context", 7) == 0) + 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 (_wcsnicmp(p, L"context", 7) == 0) { - if(sFlag) return CERR_ContextInVirtualKeySection; - p += 7; + if (sFlag) return CERR_ContextInVirtualKeySection; + p += 7; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(q && *q) - { + q = GetDelimitedString(&p, L"()", 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(_wcsnicmp(p, L"clearcontext", 12) == 0) + 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 (_wcsnicmp(p, L"clearcontext", 12) == 0) + { + p += 12; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CLEARCONTEXT; + tstr[mx] = 0; + } + else if (_wcsnicmp(p, L"call", 4) == 0) { - p += 12; - tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CLEARCONTEXT; - tstr[mx] = 0; - } - else if(_wcsnicmp(p, L"call", 4) == 0) - { VERIFY_KEYBOARD_VERSION(fk, VERSION_501, CERR_501FeatureOnly_Call); - if(sFlag) return CERR_CallInVirtualKeySection; - p += 4; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidCall; + if (sFlag) return CERR_CallInVirtualKeySection; + p += 4; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidCall; - for(i = 0; i < fk->cxStoreArray; i++) - { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } + for (i = 0; i < fk->cxStoreArray; i++) + { + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } - if(!IsValidCallStore(&fk->dpStoreArray[i])) return CERR_InvalidCall; + if (!IsValidCallStore(&fk->dpStoreArray[i])) return CERR_InvalidCall; CheckStoreUsage(fk, i, FALSE, FALSE, TRUE); - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; - tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CALL; - tstr[mx++] = (WCHAR)i+1; - tstr[mx] = 0; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_CALL; + tstr[mx++] = (WCHAR)i + 1; + tstr[mx] = 0; - fk->dpStoreArray[i].dwSystemID = TSS_CALLDEFINITION; - } - else - return CERR_InvalidToken; - continue; - case 8: - if(_wcsnicmp(p, L"notany", 6) == 0) - { + fk->dpStoreArray[i].dwSystemID = TSS_CALLDEFINITION; + } + else + return CERR_InvalidToken; + continue; + case 8: + if (_wcsnicmp(p, L"notany", 6) == 0) + { VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly) - if(sFlag) return CERR_AnyInVirtualKeySection; - p += 6; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidAny; + if (sFlag) return CERR_AnyInVirtualKeySection; + p += 6; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (!q || !*q) return CERR_InvalidAny; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_NOTANY; - tstr[mx++] = (WCHAR)i+1; // store to index + 1, avoids End-of-string - tstr[mx] = 0; - continue; - } - if(_wcsnicmp(p, L"nul", 3) != 0) return CERR_InvalidToken; + tstr[mx++] = CODE_NOTANY; + tstr[mx++] = (WCHAR)i + 1; // store to index + 1, avoids End-of-string + tstr[mx] = 0; + continue; + } + if (_wcsnicmp(p, L"nul", 3) != 0) return CERR_InvalidToken; - p += 3; + p += 3; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_NUL; - tstr[mx] = 0; - continue; - case 9: - if(_wcsnicmp(p, L"use", 3) != 0) + tstr[mx++] = CODE_NUL; + tstr[mx] = 0; + continue; + case 9: + if (_wcsnicmp(p, L"use", 3) != 0) { - if(*(p+1) == '+') + if (*(p + 1) == '+') { - n = xatoi(&p); - if(*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; - if((err = 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); + n = xatoi(&p); + if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; + if ((err = 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; + p += 3; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidUse; + q = GetDelimitedString(&p, L"()", 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(_wcsnicmp(p, L"reset", 5) == 0) + tstr[mx++] = CODE_USE; + tstr[mx] = GetGroupNum(fk, q); + if (tstr[mx] == 0) return CERR_GroupDoesNotExist; + tstr[++mx] = 0; + continue; + case 10: + if (_wcsnicmp(p, L"reset", 5) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); - if(sFlag) return CERR_InvalidInVirtualKeySection; + if (sFlag) return CERR_InvalidInVirtualKeySection; p += 5; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidReset; + if (!q || !*q) return CERR_InvalidReset; err = process_reset(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else { - if(_wcsnicmp(p, L"return", 6) != 0) return CERR_InvalidToken; + if (_wcsnicmp(p, L"return", 6) != 0) return CERR_InvalidToken; - p += 6; + p += 6; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_RETURN; - tstr[mx] = 0; - wcsncpy_s(output, max, tstr, max); // I3481 - output[max-1] = 0; - return 0; + tstr[mx] = 0; + wcsncpy_s(output, max, tstr, max); // I3481 + output[max - 1] = 0; + return 0; } continue; - case 11: - p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; + case 11: + p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; - //printf("--EXTENDEDSTRING--\n"); + //printf("--EXTENDEDSTRING--\n"); - do + do { - while(iswspace(*p)) p++; + while (iswspace(*p)) p++; - switch(towupper(*p)) - { - case 'N': - if(_wcsnicmp(p, L"NCAPS", 5) == 0) - sFlag |= NOTCAPITALFLAG, p += 5; - else finished = TRUE; - break; - case 'L': - if(_wcsnicmp(p, L"LALT", 4) == 0) - sFlag |= LALTFLAG, p += 4; - else if(_wcsnicmp(p, L"LCTRL", 5) == 0) - sFlag |= LCTRLFLAG, p += 5; - else finished = TRUE; - break; - case 'R': - if(_wcsnicmp(p, L"RALT", 4) == 0) - sFlag |= RALTFLAG, p += 4; - else if(_wcsnicmp(p, L"RCTRL", 5) == 0) - sFlag |= RCTRLFLAG, p += 5; - else finished = TRUE; - break; - case 'A': - if(_wcsnicmp(p, L"ALT", 3) == 0) - sFlag |= K_ALTFLAG, p += 3; - else finished = TRUE; - break; - case 'C': - if(_wcsnicmp(p, L"CTRL", 4) == 0) - sFlag |= K_CTRLFLAG, p += 4; - else if(_wcsnicmp(p, L"CAPS", 4) == 0) - sFlag |= CAPITALFLAG, p += 4; - else finished = TRUE; - break; - case 'S': - if(_wcsnicmp(p, L"SHIFT", 5) == 0) - sFlag |= K_SHIFTFLAG, p += 5; - else finished = TRUE; - break; - default: - finished = TRUE; - break; - } - } while(!finished); + switch (towupper(*p)) + { + case 'N': + if (_wcsnicmp(p, L"NCAPS", 5) == 0) + sFlag |= NOTCAPITALFLAG, p += 5; + else finished = TRUE; + break; + case 'L': + if (_wcsnicmp(p, L"LALT", 4) == 0) + sFlag |= LALTFLAG, p += 4; + else if (_wcsnicmp(p, L"LCTRL", 5) == 0) + sFlag |= LCTRLFLAG, p += 5; + else finished = TRUE; + break; + case 'R': + if (_wcsnicmp(p, L"RALT", 4) == 0) + sFlag |= RALTFLAG, p += 4; + else if (_wcsnicmp(p, L"RCTRL", 5) == 0) + sFlag |= RCTRLFLAG, p += 5; + else finished = TRUE; + break; + case 'A': + if (_wcsnicmp(p, L"ALT", 3) == 0) + sFlag |= K_ALTFLAG, p += 3; + else finished = TRUE; + break; + case 'C': + if (_wcsnicmp(p, L"CTRL", 4) == 0) + sFlag |= K_CTRLFLAG, p += 4; + else if (_wcsnicmp(p, L"CAPS", 4) == 0) + sFlag |= CAPITALFLAG, p += 4; + else finished = TRUE; + break; + case 'S': + if (_wcsnicmp(p, L"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); @@ -2277,70 +2284,70 @@ DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int ma // 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) && - CompileTarget == CKF_KEYMANWEB && - fk->dwFlags & KF_AUTOMATICVERSION) { + CompileTarget == CKF_KEYMANWEB && + fk->dwFlags & KF_AUTOMATICVERSION) { VERIFY_KEYBOARD_VERSION(fk, VERSION_100, 0); } - //printf("sFlag: %x\n", sFlag); + //printf("sFlag: %x\n", sFlag); tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_EXTENDED; - tstr[mx++] = sFlag; + tstr[mx++] = CODE_EXTENDED; + tstr[mx++] = sFlag; - while(iswspace(*p)) p++; + while (iswspace(*p)) p++; - q = p; + q = p; - if(*q == ']') + 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 == '"') - { + while (*q != ']') + { + if (*q == '\'' || *q == '"') + { VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_VirtualCharKey); - if(!FMnemonicLayout) AddWarning(CWARN_VirtualCharKeyWithPositionalLayout); - 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 */ - } + if (!FMnemonicLayout) AddWarning(CWARN_VirtualCharKeyWithPositionalLayout); + 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++); + for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); - if(*q == 0) return CERR_InvalidToken; + if (*q == 0) return CERR_InvalidToken; WCHAR vkname[SZMAX_VKDICTIONARYNAME]; // I3438 - if(j >= SZMAX_VKDICTIONARYNAME) return CERR_InvalidToken; + if (j >= SZMAX_VKDICTIONARYNAME) return CERR_InvalidToken; wcsncpy_s(vkname, _countof(vkname), p, j); // I3481 vkname[j] = 0; - if(_wcsicmp(vkname, L"K_NPENTER") == 0) - i = 5; // I649 - K_NPENTER hack - else + if (_wcsicmp(vkname, L"K_NPENTER") == 0) + i = 5; // I649 - K_NPENTER hack + else { - for(i = 0; i <= VK__MAX; i++) - { - if(_wcsicmp(vkname, VKeyNames[i]) == 0 || _wcsicmp(vkname, VKeyISO9995Names[i]) == 0) - break; - } + for (i = 0; i <= VK__MAX; i++) + { + if (_wcsicmp(vkname, VKeyNames[i]) == 0 || _wcsicmp(vkname, VKeyISO9995Names[i]) == 0) + break; + } } - if(i == VK__MAX + 1) + if (i == VK__MAX + 1) { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_InvalidToken); i = GetVKCode(fk, vkname); // I3438 - if(i == 0) + if (i == 0) return CERR_InvalidToken; } @@ -2348,134 +2355,134 @@ DWORD GetXString(PFILE_KEYBOARD fk, PWSTR str, PWSTR token, PWSTR output, int ma tstr[mx++] = (int)i; - if(FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) AddWarning(CWARN_VirtualKeyWithMnemonicLayout); // I3438 + if (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"); + while (iswspace(*q)) q++; + } + tstr[mx++] = UC_SENTINEL_EXTENDEDEND; + tstr[mx] = 0; + //printf("--EXTENDEDEND--\n"); - p = q+1; + p = q + 1; - sFlag = 0; + sFlag = 0; - continue; - case 14: - if(_wcsnicmp(p, L"set", 3) == 0) + continue; + case 14: + if (_wcsnicmp(p, L"set", 3) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); p += 3; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidSet; + if (!q || !*q) return CERR_InvalidSet; err = process_set(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } - else if(_wcsnicmp(p, L"save", 4) == 0) + else if (_wcsnicmp(p, L"save", 4) == 0) { VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); p += 4; q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidSave; + if (!q || !*q) return CERR_InvalidSave; err = process_save(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; } else { - if(_wcsnicmp(p, L"switch", 6) != 0) return CERR_InvalidToken; - p += 6; - q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); - if(!q || !*q) return CERR_InvalidSwitch; + if (_wcsnicmp(p, L"switch", 6) != 0) return CERR_InvalidToken; + p += 6; + q = GetDelimitedString(&p, L"()", 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; + tstr[mx++] = CODE_SWITCH; + tstr[mx++] = atoiW(q); + tstr[mx] = 0; } - continue; - case 15: - if(_wcsnicmp(p, L"fix", 3) == 0) + continue; + case 15: + if (_wcsnicmp(p, L"fix", 3) == 0) { - p += 3; + p += 3; tstr[mx++] = UC_SENTINEL; - tstr[mx++] = CODE_CLEARCONTEXT; - tstr[mx] = 0; - } - else - return CERR_InvalidToken; - continue; - case 16: + 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(iswalnum(*q) || *q == '-' || *q == '_') q++; - c = *q; *q = 0; - codename = wstrtostr(p+1); - *q = c; - n = CodeConstants->GetCode(codename, &i); - delete codename; - if(n == 0) return CERR_InvalidNamedCode; - if(i < 0xFFFFFFFFL) 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; + q = p + 1; + while (iswalnum(*q) || *q == '-' || *q == '_') q++; + c = *q; *q = 0; + codename = wstrtostr(p + 1); + *q = c; + n = CodeConstants->GetCode(codename, &i); + delete[] codename; + if (n == 0) return CERR_InvalidNamedCode; + if (i < 0xFFFFFFFFL) 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(_wcsnicmp(p, L"platform", 8) != 0) return CERR_InvalidToken; // I3430 + if (_wcsnicmp(p, L"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, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 8; + q = GetDelimitedString(&p, L"()", GDS_CUTLEAD | GDS_CUTFOLL); if (!q || !*q) return CERR_InvalidToken; err = process_platform(fk, q, tstr, &mx); - if(err != CERR_None) return err; + if (err != CERR_None) return err; continue; case 18: // I3437 - if(_wcsnicmp(p, L"layer", 5) != 0) return CERR_InvalidToken; + if (_wcsnicmp(p, L"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, L"()", GDS_CUTLEAD | GDS_CUTFOLL); + if (sFlag) return CERR_InvalidInVirtualKeySection; + p += 5; + q = GetDelimitedString(&p, L"()", 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; + if (err != CERR_None) return err; continue; - default: - return CERR_InvalidToken; - } - if(tokenFound) + default: + return CERR_InvalidToken; + } + if (tokenFound) { - *newp = p; - wcsncpy_s(output, max, tstr, max); // I3481 - output[max-1] = 0; - ErrChr = 0; - return CERR_None; - } - if(mx >= max) return CERR_BufferOverflow; - } while(*p); + *newp = p; + wcsncpy_s(output, max, tstr, max); // I3481 + output[max - 1] = 0; + ErrChr = 0; + return CERR_None; + } + if (mx >= max) return CERR_BufferOverflow; + } while (*p); - if(!*token) + if (!*token) { - *newp = p; - wcsncpy_s(output, max, tstr, max); // I3481 - output[max-1] = 0; - ErrChr = 0; + *newp = p; + wcsncpy_s(output, max, tstr, max); // I3481 + output[max - 1] = 0; + ErrChr = 0; return CERR_None; } } __finally { - delete tstr; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer - GetXString is re-entrant with if() + delete[] tstr; // I2432 - Allocate buffers each line -- slightly slower but safer than keeping a single buffer - GetXString is re-entrant with if() } - return CERR_NoTokensFound; + return CERR_NoTokensFound; } DWORD process_if_synonym(DWORD dwSystemID, PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx); // I3430 @@ -2500,28 +2507,28 @@ DWORD process_if_synonym(DWORD dwSystemID, PFILE_KEYBOARD fk, LPWSTR q, LPWSTR t PWSTR r; - if((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) { - delete temp; - return msg; + delete temp; + return msg; } DWORD dwStoreID; - if((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) + if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) { delete temp; return msg; } tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) CODE_IFSYSTEMSTORE; - tstr[(*mx)++] = (WCHAR)(dwSystemID+1); // I4785 + tstr[(*mx)++] = (WCHAR)CODE_IFSYSTEMSTORE; + tstr[(*mx)++] = (WCHAR)(dwSystemID + 1); // I4785 tstr[(*mx)++] = 2; - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; - delete temp; + delete[] temp; return CERR_None; } @@ -2531,66 +2538,66 @@ DWORD process_if(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) // I3431 /* if( <'='|'!='> ) */ DWORD i, code, not = FALSE; LPWSTR r = q, s = q; - while(*s && *s != L' ' && *s != L'!' && *s != L'=') s++; + while (*s && *s != L' ' && *s != L'!' && *s != L'=') s++; r = s; - while(*s == L' ') s++; - if(*s == L'!') + while (*s == L' ') s++; + if (*s == L'!') { s++; not = TRUE; } - if(*s != '=') return CERR_InvalidIf; + if (*s != '=') return CERR_InvalidIf; s++; - while(*s == ' ') s++; + while (*s == ' ') s++; *r = 0; r = q; - if(r[0] == '&') + if (r[0] == '&') { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); - for(i = 0; StoreTokens[i]; i++) - { - if(_wcsicmp(r, StoreTokens[i]) == 0) break; - } - if(!StoreTokens[i]) return CERR_IfSystemStore_NotFound; + for (i = 0; StoreTokens[i]; i++) + { + if (_wcsicmp(r, StoreTokens[i]) == 0) break; + } + if (!StoreTokens[i]) return CERR_IfSystemStore_NotFound; code = CODE_IFSYSTEMSTORE; } else { - code = CODE_IFOPT; + code = CODE_IFOPT; - for(i = 0; i < fk->cxStoreArray; i++) - { - if(_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; - } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; - CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); + for (i = 0; i < fk->cxStoreArray; i++) + { + if (_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; + } + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); } PWCHAR temp = new WCHAR[GLOBAL_BUFSIZE]; DWORD msg; - if((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) { - delete temp; - return msg; + delete[] temp; + return msg; } DWORD dwStoreID; - if((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) + if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) { - delete temp; + delete[] temp; return msg; } tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) code; - tstr[(*mx)++] = (WCHAR)(i+1); + tstr[(*mx)++] = (WCHAR)code; + tstr[(*mx)++] = (WCHAR)(i + 1); tstr[(*mx)++] = not ? 1 : 2; - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; return CERR_None; @@ -2600,16 +2607,16 @@ DWORD process_reset(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) { /* reset() */ DWORD i; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = CODE_RESETOPT; - tstr[(*mx)++] = (WCHAR)(i+1); + tstr[(*mx)++] = (WCHAR)(i + 1); tstr[(*mx)] = 0; return CERR_None; @@ -2622,22 +2629,22 @@ DWORD process_set_synonym(DWORD dwSystemID, PFILE_KEYBOARD fk, LPWSTR q, LPWSTR PWCHAR temp = new WCHAR[GLOBAL_BUFSIZE], r; DWORD msg; - if((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) - { - delete temp; - return msg; - } + if ((msg = GetXString(fk, q, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } DWORD dwStoreID; msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); - delete temp; - if(msg != CERR_None) return msg; + delete[] temp; + if (msg != CERR_None) return msg; tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) CODE_SETSYSTEMSTORE; - tstr[(*mx)++] = (WCHAR)(dwSystemID+1); - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)CODE_SETSYSTEMSTORE; + tstr[(*mx)++] = (WCHAR)(dwSystemID + 1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; return CERR_None; } @@ -2646,25 +2653,25 @@ DWORD process_set(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) { /* set( <'='> */ LPWSTR r = q, s = q; // I3440 - while(*s && *s != L' ' && *s != L'=') s++; + while (*s && *s != L' ' && *s != L'=') s++; r = s; - while(*s == L' ') s++; - if(*s != '=') return CERR_InvalidSet; + while (*s == L' ') s++; + if (*s != '=') return CERR_InvalidSet; s++; - while(*s == ' ') s++; + while (*s == ' ') s++; *r = 0; r = q; DWORD i, code; - if(r[0] == '&') + if (r[0] == '&') { VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_SetSystemStores); // I3437 - for(i = 0; StoreTokens[i]; i++) - { - if(_wcsicmp(r, StoreTokens[i]) == 0) break; - } - if(!StoreTokens[i]) return CERR_SetSystemStore_NotFound; + for (i = 0; StoreTokens[i]; i++) + { + if (_wcsicmp(r, StoreTokens[i]) == 0) break; + } + if (!StoreTokens[i]) return CERR_SetSystemStore_NotFound; code = CODE_SETSYSTEMSTORE; } else @@ -2672,11 +2679,11 @@ DWORD process_set(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) wchar_t *context = NULL; LPWSTR r = wcstok_s(q, L" =", &context); // I3481 - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; + if (_wcsicmp(r, fk->dpStoreArray[i].szName) == 0) break; } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); code = CODE_SETOPT; } @@ -2687,22 +2694,22 @@ DWORD process_set(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) //r = wcstok(NULL, L" ="); - if((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE-1, 0, &r, FALSE, TRUE)) != CERR_None) - { - delete temp; - return msg; - } + if ((msg = GetXString(fk, s, L"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + { + delete[] temp; + return msg; + } DWORD dwStoreID; msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); - delete temp; - if(msg != CERR_None) return msg; + delete[] temp; + if (msg != CERR_None) return msg; tstr[(*mx)++] = UC_SENTINEL; - tstr[(*mx)++] = (WCHAR) code; - tstr[(*mx)++] = (WCHAR)(i+1); - tstr[(*mx)++] = (WCHAR)(dwStoreID+1); + tstr[(*mx)++] = (WCHAR)code; + tstr[(*mx)++] = (WCHAR)(i + 1); + tstr[(*mx)++] = (WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; return CERR_None; } @@ -2711,82 +2718,82 @@ DWORD process_save(PFILE_KEYBOARD fk, LPWSTR q, LPWSTR tstr, int *mx) { /* save() */ DWORD i; - for(i = 0; i < fk->cxStoreArray; i++) + for (i = 0; i < fk->cxStoreArray; i++) { - if(_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; + if (_wcsicmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if(i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = CODE_SAVEOPT; - tstr[(*mx)++] = (WCHAR)(i+1); + tstr[(*mx)++] = (WCHAR)(i + 1); tstr[(*mx)] = 0; return CERR_None; } int xatoi(PWSTR *p) { - PWSTR endptr; - int n; + PWSTR endptr; + int n; - switch(towupper(**p)) - { - case 'U': - (*p)++; - if(**p != '+') return 0; - (*p)++; - n = (int)wcstol(*p, &endptr, 16); - *p = endptr; - break; - case 'X': - (*p)++; - n = (int)wcstol(*p, &endptr, 16); - *p = endptr; - break; - case 'D': - (*p)++; - n = (int)wcstol(*p, &endptr, 10); - *p = endptr; - break; - default: - n = (int)wcstol(*p, &endptr, 8); - *p = endptr; - break; - } - return n; + switch (towupper(**p)) + { + case 'U': + (*p)++; + if (**p != '+') return 0; + (*p)++; + n = (int)wcstol(*p, &endptr, 16); + *p = endptr; + break; + case 'X': + (*p)++; + n = (int)wcstol(*p, &endptr, 16); + *p = endptr; + break; + case 'D': + (*p)++; + n = (int)wcstol(*p, &endptr, 10); + *p = endptr; + break; + default: + n = (int)wcstol(*p, &endptr, 8); + *p = endptr; + break; + } + return n; } int GetGroupNum(PFILE_KEYBOARD fk, PWSTR p) { - PFILE_GROUP gp; - DWORD i; + PFILE_GROUP gp; + DWORD i; - for(i = 0, gp = fk->dpGroupArray; i < fk->cxGroupArray; gp++, i++) - { - if(_wcsicmp(gp->szName, p) == 0) return i + 1; - } - return 0; + for (i = 0, gp = fk->dpGroupArray; i < fk->cxGroupArray; gp++, i++) + { + if (_wcsicmp(gp->szName, p) == 0) return i + 1; + } + return 0; } DWORD ProcessEthnologueStore(PWSTR p) // I2646 { DWORD res = CERR_None; - PWSTR q = NULL; - while(*p) + PWSTR q = NULL; + while (*p) { - while(wcschr(L" ,;", *p)) + while (wcschr(L" ,;", *p)) { - if(*p != ' ') res = CWARN_PunctuationInEthnologueCode; + if (*p != ' ') res = CWARN_PunctuationInEthnologueCode; p++; } - if(q == p) return CERR_InvalidEthnologueCode; - if(*p) + if (q == p) return CERR_InvalidEthnologueCode; + if (*p) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { - if(!iswalpha(*p)) return CERR_InvalidEthnologueCode; + if (!iswalpha(*p)) return CERR_InvalidEthnologueCode; p++; } } @@ -2799,13 +2806,13 @@ DWORD ProcessEthnologueStore(PWSTR p) // I2646 DWORD ProcessHotKey(PWSTR p, DWORD *hk) { - PWSTR q, r; - DWORD sFlag; - int j, i; + PWSTR q, r; + DWORD sFlag; + int j, i; - *hk = 0; + *hk = 0; - if(*p == UC_SENTINEL && *(p+1) == CODE_EXTENDED) { + if (*p == UC_SENTINEL && *(p + 1) == CODE_EXTENDED) { WORD Key = *(p + 3); WORD ShiftFlags = *(p + 2); @@ -2824,83 +2831,83 @@ DWORD ProcessHotKey(PWSTR p, DWORD *hk) return CERR_None; } - q = wcschr(p, '['); - if(q) + q = wcschr(p, '['); + if (q) + { + q++; + sFlag = 0; + + do { - q++; - sFlag = 0; + while (iswspace(*q)) q++; - do - { - while(iswspace(*q)) q++; + if (_wcsnicmp(q, L"ALT", 3) == 0) sFlag |= HK_ALT, q += 3; + else if (_wcsnicmp(q, L"CTRL", 4) == 0) sFlag |= HK_CTRL, q += 4; + else if (_wcsnicmp(q, L"SHIFT", 5) == 0) sFlag |= HK_SHIFT, q += 5; + else if (towupper(*q) != 'K') return CERR_InvalidToken; + } while (towupper(*q) != 'K'); - if(_wcsnicmp(q, L"ALT", 3) == 0) sFlag |= HK_ALT, q += 3; - else if(_wcsnicmp(q, L"CTRL", 4) == 0) sFlag |= HK_CTRL, q += 4; - else if(_wcsnicmp(q, L"SHIFT", 5) == 0) sFlag |= HK_SHIFT, q += 5; - else if(towupper(*q) != 'K') return CERR_InvalidToken; - } while(towupper(*q) != 'K'); - - r = wcschr(q, ']'); - if(r) - { - r--; - while(iswspace(*r) && r > q) r--; - r++; - } - else return CERR_NoTokensFound; - - j = (int)(INT_PTR) (r-q); - - for(i = 0; i <= VK__MAX; i++) // I3438 - if( j == (int)wcslen(VKeyNames[i]) && _wcsnicmp(q, VKeyNames[i], j) == 0) break; - - if(i == VK__MAX + 1) return CERR_InvalidToken; // I3438 - - *hk = i | sFlag; - - return CERR_None; - } - - q = GetDelimitedString(&p, L"\"\"", GDS_CUTLEAD | GDS_CUTFOLL); - if(q) + r = wcschr(q, ']'); + if (r) { - if(wcschr(q, '^')) *hk |= HK_CTRL; - if(wcschr(q, '+')) *hk |= HK_SHIFT; - if(wcschr(q, '%')) *hk |= HK_ALT; - q = wcschr(q, 0) - 1; - *hk |= *q; - return CERR_None; - } + r--; + while (iswspace(*r) && r > q) r--; + r++; + } + else return CERR_NoTokensFound; - return CERR_CodeInvalidInThisSection; + j = (int)(INT_PTR)(r - q); + + for (i = 0; i <= VK__MAX; i++) // I3438 + if (j == (int)wcslen(VKeyNames[i]) && _wcsnicmp(q, VKeyNames[i], j) == 0) break; + + if (i == VK__MAX + 1) return CERR_InvalidToken; // I3438 + + *hk = i | sFlag; + + return CERR_None; + } + + q = GetDelimitedString(&p, L"\"\"", GDS_CUTLEAD | GDS_CUTFOLL); + if (q) + { + if (wcschr(q, '^')) *hk |= HK_CTRL; + if (wcschr(q, '+')) *hk |= HK_SHIFT; + if (wcschr(q, '%')) *hk |= HK_ALT; + q = wcschr(q, 0) - 1; + *hk |= *q; + return CERR_None; + } + + return CERR_CodeInvalidInThisSection; } void SetChecksum(LPBYTE buf, LPDWORD CheckSum, DWORD sz) { - BuildCRCTable(); - *CheckSum = CalculateBufferCRC(buf, sz); + BuildCRCTable(); + *CheckSum = CalculateBufferCRC(buf, sz); } BOOL CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, BOOL fIsStore, BOOL fIsOption, BOOL fIsCall) { PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; - if(fIsStore && !sp->fIsStore) + if (fIsStore && !sp->fIsStore) { - if(sp->fIsDebug || sp->fIsOption || sp->fIsReserved || sp->fIsCall) + if (sp->fIsDebug || sp->fIsOption || sp->fIsReserved || sp->fIsCall) AddWarning(CWARN_StoreAlreadyUsedAsOptionOrCall); sp->fIsStore = TRUE; } - else if(fIsOption && !sp->fIsOption) + else if (fIsOption && !sp->fIsOption) { - if(sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsCall) + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsCall) AddWarning(CWARN_StoreAlreadyUsedAsStoreOrCall); sp->fIsOption = TRUE; } - else if(fIsCall && !sp->fIsCall) + else if (fIsCall && !sp->fIsCall) { - if(sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsOption) + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsOption) AddWarning(CWARN_StoreAlreadyUsedAsStoreOrOption); sp->fIsCall = TRUE; } @@ -2910,440 +2917,450 @@ BOOL CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, BOOL fIsStore, BOOL fIsO DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, HANDLE hOutfile) { - PFILE_GROUP fgp; - PFILE_STORE fsp; - PFILE_KEY fkp; + PFILE_GROUP fgp; + PFILE_STORE fsp; + PFILE_KEY fkp; - PCOMP_KEYBOARD ck; - PCOMP_GROUP gp; - PCOMP_STORE sp; - PCOMP_KEY kp; - PBYTE buf; - size_t offset; + PCOMP_KEYBOARD ck; + PCOMP_GROUP gp; + PCOMP_STORE sp; + PCOMP_KEY kp; + PBYTE buf; + size_t offset; size_t size; - DWORD i, j; + DWORD i, j; - // Calculate how much memory to allocate + // 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; + 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++) + for (i = 0, fgp = fk->dpGroupArray; i < fk->cxGroupArray; i++, fgp++) + { + if (FSaveDebug) size += wcslen(fgp->szName) * 2 + 2; + size += fgp->cxKeyArray * sizeof(COMP_KEY); + for (j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) { - if(FSaveDebug) size += wcslen(fgp->szName)*2 + 2; - size += fgp->cxKeyArray * sizeof(COMP_KEY); - for(j = 0, fkp = fgp->dpKeyArray; j < fgp->cxKeyArray; j++, fkp++) - { - size += wcslen(fkp->dpOutput)*2 + 2; - size += wcslen(fkp->dpContext)*2 + 2; - } + 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; - } + if (fgp->dpMatch) size += wcslen(fgp->dpMatch) * 2 + 2; + if (fgp->dpNoMatch) size += wcslen(fgp->dpNoMatch) * 2 + 2; + } - for(i = 0; i < fk->cxStoreArray; i++) - { - size += wcslen(fk->dpStoreArray[i].dpString)*2 + 2; - if(FSaveDebug || fk->dpStoreArray[i].fIsOption) size += wcslen(fk->dpStoreArray[i].szName)*2 + 2; - } + for (i = 0; i < fk->cxStoreArray; i++) + { + size += wcslen(fk->dpStoreArray[i].dpString) * 2 + 2; + if (FSaveDebug || fk->dpStoreArray[i].fIsOption) size += wcslen(fk->dpStoreArray[i].szName) * 2 + 2; + } - buf = new BYTE[size]; - if(!buf) return CERR_CannotAllocateMemory; - memset(buf, 0, size); + buf = new BYTE[size]; + if (!buf) return CERR_CannotAllocateMemory; + memset(buf, 0, size); - ck = (PCOMP_KEYBOARD) buf; + ck = (PCOMP_KEYBOARD)buf; - ck->dwIdentifier = FILEID_COMPILED; + 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->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; + ck->dwFlags = fk->dwFlags; - offset = sizeof(COMP_KEYBOARD); + offset = sizeof(COMP_KEYBOARD); - /*ck->dpLanguageName = offset; - wcscpy((PWSTR)(buf + offset), fk->szLanguageName); - offset += wcslen(fk->szLanguageName)*2 + 2; + /*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->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->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->dpMessage = offset; + wcscpy((PWSTR)(buf + offset), fk->szMessage); + offset += wcslen(fk->szMessage)*2 + 2;*/ - ck->dpStoreArray = (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++ ) + ck->dpStoreArray = (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 = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fsp->dpString); // I3481 // I3641 + offset += wcslen(fsp->dpString) * 2 + 2; + + if (FSaveDebug || fsp->fIsOption) { - sp->dwSystemID = fsp->dwSystemID; - sp->dpString = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fsp->dpString); // I3481 // I3641 - offset += wcslen(fsp->dpString)*2 + 2; + sp->dpName = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fsp->szName); // I3481 // I3641 + offset += wcslen(fsp->szName) * 2 + 2; + } + else sp->dpName = 0; + } - if(FSaveDebug || fsp->fIsOption) - { - sp->dpName = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fsp->szName); // I3481 // I3641 - offset += wcslen(fsp->szName)*2 + 2; - } - else sp->dpName = 0; - } + ck->dpGroupArray = (DWORD)offset; + gp = (PCOMP_GROUP)(buf + offset); + fgp = fk->dpGroupArray; - ck->dpGroupArray = (DWORD) offset; - gp = (PCOMP_GROUP)(buf+offset); - fgp = fk->dpGroupArray; + offset += sizeof(COMP_GROUP) * ck->cxGroupArray; - offset += sizeof(COMP_GROUP) * ck->cxGroupArray; + for (i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) + { + gp->cxKeyArray = fgp->cxKeyArray; + gp->fUsingKeys = fgp->fUsingKeys; - for(i = 0; i < ck->cxGroupArray; i++, gp++, fgp++) + gp->dpMatch = gp->dpNoMatch = 0; + + if (fgp->dpMatch) { - gp->cxKeyArray = fgp->cxKeyArray; - gp->fUsingKeys = fgp->fUsingKeys; + gp->dpMatch = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fgp->dpMatch); // I3481 // I3641 + offset += wcslen(fgp->dpMatch) * 2 + 2; + } + if (fgp->dpNoMatch) + { + gp->dpNoMatch = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fgp->dpNoMatch); // I3481 // I3641 + offset += wcslen(fgp->dpNoMatch) * 2 + 2; + } - gp->dpMatch = gp->dpNoMatch = 0; + if (FSaveDebug) + { + gp->dpName = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fgp->szName); // I3481 // I3641 + offset += wcslen(fgp->szName) * 2 + 2; + } + else gp->dpName = 0; - if(fgp->dpMatch) - { - gp->dpMatch = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fgp->dpMatch); // I3481 // I3641 - offset += wcslen(fgp->dpMatch)*2 + 2; - } - if(fgp->dpNoMatch) - { - gp->dpNoMatch = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fgp->dpNoMatch); // I3481 // I3641 - offset += wcslen(fgp->dpNoMatch)*2 + 2; - } + gp->dpKeyArray = (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->Key = fkp->Key; + if (FSaveDebug) kp->Line = fkp->Line; else kp->Line = 0; + kp->ShiftFlags = fkp->ShiftFlags; + kp->dpOutput = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fkp->dpOutput); // I3481 // I3641 + offset += wcslen(fkp->dpOutput) * 2 + 2; + kp->dpContext = (DWORD)offset; + wcscpy_s((PWSTR)(buf + offset), (size - offset) / sizeof(WCHAR), fkp->dpContext); // I3481 // I3641 + offset += wcslen(fkp->dpContext) * 2 + 2; + } + } - if(FSaveDebug) - { - gp->dpName = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fgp->szName); // I3481 // I3641 - offset += wcslen(fgp->szName)*2 + 2; - } - else gp->dpName = 0; + ck->dwBitmapSize = fk->dwBitmapSize; + ck->dpBitmapOffset = (DWORD)offset; + memcpy(buf + offset, fk->lpBitmap, fk->dwBitmapSize); + offset += fk->dwBitmapSize; - gp->dpKeyArray = (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->Key = fkp->Key; - if(FSaveDebug) kp->Line = fkp->Line; else kp->Line = 0; - kp->ShiftFlags = fkp->ShiftFlags; - kp->dpOutput = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpOutput); // I3481 // I3641 - offset += wcslen(fkp->dpOutput)*2 + 2; - kp->dpContext = (DWORD) offset; - wcscpy_s((PWSTR)(buf+offset), (size-offset) / sizeof(WCHAR), fkp->dpContext); // I3481 // I3641 - offset += wcslen(fkp->dpContext)*2 + 2; - } - } + if (offset != size) { + delete[] buf; + return CERR_SomewhereIGotItWrong; + } - ck->dwBitmapSize = fk->dwBitmapSize; - ck->dpBitmapOffset = (DWORD) offset; - memcpy(buf + offset, fk->lpBitmap, fk->dwBitmapSize); - offset += fk->dwBitmapSize; - - if(offset != size) return CERR_SomewhereIGotItWrong; - - SetChecksum(buf, &ck->dwCheckSum, (DWORD) size); + SetChecksum(buf, &ck->dwCheckSum, (DWORD)size); DWORD dwBytesWritten = 0; - WriteFile(hOutfile, buf, (DWORD) size, &dwBytesWritten, NULL); + WriteFile(hOutfile, buf, (DWORD)size, &dwBytesWritten, NULL); - if(dwBytesWritten != size) return CERR_UnableToWriteFully; + if (dwBytesWritten != size) { + delete[] buf; + return CERR_UnableToWriteFully; + } - delete buf; + delete[] buf; - return CERR_None; + return CERR_None; } DWORD ReadLine(HANDLE hInfile, PWSTR wstr, BOOL PreProcess) { - DWORD len; - PWSTR p; - BOOL LineCarry = FALSE, InComment = FALSE; - DWORD n; - WCHAR currentQuotes = 0; + DWORD len; + PWSTR p; + BOOL LineCarry = FALSE, InComment = FALSE; + DWORD n; + WCHAR currentQuotes = 0; WCHAR str[LINESIZE + 3]; - if(!ReadFile(hInfile, str, LINESIZE*2, &len, NULL)) return CERR_CannotReadInfile; - len /= 2; - str[len] = 0; + if (!ReadFile(hInfile, str, LINESIZE * 2, &len, NULL)) return CERR_CannotReadInfile; + len /= 2; + str[len] = 0; - if(SetFilePointer(hInfile, 0, NULL, FILE_CURRENT) == GetFileSize(hInfile, NULL)) - // Always a "\r\n" to the EOF, avoids funny bugs - wcscat_s(str, _countof(str), L"\r\n"); // I3481 + if (SetFilePointer(hInfile, 0, NULL, FILE_CURRENT) == GetFileSize(hInfile, NULL)) + // Always a "\r\n" to the EOF, avoids funny bugs + wcscat_s(str, _countof(str), L"\r\n"); // I3481 - if(len == 0) return CERR_EndOfFile; + if (len == 0) return CERR_EndOfFile; - for(p = str, n = 0; n < len; n++, p++) + for (p = str, n = 0; n < len; n++, p++) + { + if (currentQuotes != 0) { - if(currentQuotes != 0) - { - if( *p == L'\n' ) + if (*p == L'\n') { *p = 0; // I2525 - wcscpy_s(wstr, LINESIZE, str); // I3481 - return (PreProcess ? CERR_None : CERR_UnterminatedString); + wcscpy_s(wstr, LINESIZE, str); // 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': + currentLine++; + LineCarry = FALSE; + *p = L' '; + continue; } - 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': - currentLine++; - LineCarry = FALSE; - *p = L' '; - continue; - } *p = 0; // I2525 wcscpy_s(wstr, LINESIZE, str); // 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 - wcscpy_s(wstr, LINESIZE, str); // I3481 - if(len == LINESIZE) - return (PreProcess ? CERR_None : CERR_LineTooLong); + return (PreProcess ? CERR_None : CERR_InvalidLineContinuation); } - if( *p == L'\n' ) currentLine++; + 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; + } + } - SetFilePointer(hInfile, -(int)(len*2 - (INT_PTR)(p-str)*2 - 2), NULL, FILE_CURRENT); + if (n == len) + { + str[LINESIZE - 1] = 0; // I2525 + wcscpy_s(wstr, LINESIZE, str); // I3481 + if (len == LINESIZE) + return (PreProcess ? CERR_None : CERR_LineTooLong); + } - p--; - while(p >= str && iswspace(*p)) p--; - p++; - *p++ = L'\n'; - *p = 0; - // trim spaces now, why not? + if (*p == L'\n') currentLine++; + + SetFilePointer(hInfile, -(int)(len * 2 - (INT_PTR)(p - str) * 2 - 2), NULL, FILE_CURRENT); + + p--; + while (p >= str && iswspace(*p)) p--; + p++; + *p++ = L'\n'; + *p = 0; + // trim spaces now, why not? wcscpy_s(wstr, LINESIZE, str); // I3481 - return CERR_None; + return CERR_None; } DWORD GetRHS(PFILE_KEYBOARD fk, PWSTR p, PWSTR buf, int bufsize, int offset, int IsUnicode) { - PWSTR q; + PWSTR q; - p = wcschr(p, '>'); + p = wcschr(p, '>'); - if(!p) return CERR_NoTokensFound; + if (!p) return CERR_NoTokensFound; - p++; + p++; - return GetXString(fk, p, L"c\n", buf, bufsize, offset, &q, TRUE, IsUnicode); + return GetXString(fk, p, L"c\n", buf, bufsize, offset, &q, TRUE, IsUnicode); } void safe_wcsncpy(PWSTR out, PWSTR in, int cbMax) { - wcsncpy_s(out, cbMax, in, cbMax); // I3481 - out[cbMax-1] = 0; + wcsncpy_s(out, cbMax, in, cbMax - 1); // I3481 + out[cbMax - 1] = 0; } BOOL IsSameToken(PWSTR *p, PWSTR token) { - PWSTR q; - q = *p; - while(iswspace(*q)) q++; - if(_wcsnicmp(q, token, wcslen(token)) == 0) - { - q += wcslen(token); - while(iswspace(*q)) q++; - *p = q; - return TRUE; - } - return FALSE; + PWSTR q; + q = *p; + while (iswspace(*q)) q++; + if (_wcsnicmp(q, token, wcslen(token)) == 0) + { + q += wcslen(token); + while (iswspace(*q)) q++; + *p = q; + return TRUE; + } + return FALSE; } BOOL IsRelativePath(char *p) { - // Relative path (returns TRUE): - // ..\...\BITMAP.BMP - // PATH\BITMAP.BMP - // BITMAP.BMP + // Relative path (returns TRUE): + // ..\...\BITMAP.BMP + // PATH\BITMAP.BMP + // BITMAP.BMP - // Semi-absolute path (returns FALSE): - // \...\BITMAP.BMP + // Semi-absolute path (returns FALSE): + // \...\BITMAP.BMP - // Absolute path (returns FALSE): - // C:\...\BITMAP.BMP - // \\SERVER\SHARE\...\BITMAP.BMP + // Absolute path (returns FALSE): + // C:\...\BITMAP.BMP + // \\SERVER\SHARE\...\BITMAP.BMP - if(*p == '\\') return FALSE; - if(*p && *(p+1) == ':') return FALSE; + if (*p == '\\') return FALSE; + if (*p && *(p + 1) == ':') return FALSE; - return TRUE; + return TRUE; } DWORD ImportBitmapFile(PFILE_KEYBOARD fk, PWSTR szName, PDWORD FileSize, PBYTE *Buf) { - HANDLE hFile; - char szNewName[260], *p; + HANDLE hFile; + char szNewName[260], *p; - p = wstrtostr(szName); + p = wstrtostr(szName); - if(IsRelativePath(p)) - { - strcpy_s(szNewName, _countof(szNewName), CompileDir); // I3481 - strcat_s(szNewName, _countof(szNewName), p); // I3481 - } - else - strcpy_s(szNewName, _countof(szNewName), p); // I3481 + if (IsRelativePath(p)) + { + strcpy_s(szNewName, _countof(szNewName), CompileDir); // I3481 + strcat_s(szNewName, _countof(szNewName), p); // I3481 + } + else + strcpy_s(szNewName, _countof(szNewName), p); // I3481 - hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile == INVALID_HANDLE_VALUE) - { - strcat_s(szNewName, _countof(szNewName), ".bmp"); // I3481 - hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile == INVALID_HANDLE_VALUE) return CERR_CannotReadBitmapFile; - } + hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + strcat_s(szNewName, _countof(szNewName), ".bmp"); // I3481 + hFile = CreateFileA(szNewName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) return CERR_CannotReadBitmapFile; + } - delete p; + delete[] p; - *FileSize = GetFileSize(hFile, NULL); + *FileSize = GetFileSize(hFile, NULL); - if(*FileSize < 2) return CERR_CannotReadBitmapFile; + if (*FileSize < 2) return CERR_CannotReadBitmapFile; - *Buf = new BYTE[*FileSize]; + *Buf = new BYTE[*FileSize]; - if(!ReadFile(hFile, *Buf, *FileSize, FileSize, NULL)) return CERR_CannotReadBitmapFile; + if (!ReadFile(hFile, *Buf, *FileSize, FileSize, NULL)) { + delete[] * Buf; + *Buf = NULL; + return CERR_CannotReadBitmapFile; + } - CloseHandle(hFile); + CloseHandle(hFile); - /* Test for version 7.0 icon support */ + /* Test for version 7.0 icon support */ if (*((PCHAR)*Buf) != 'B' && *(((PCHAR)*Buf) + 1) != 'M') { VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); } - return CERR_None; + return CERR_None; } int atoiW(PWSTR p) { - PSTR q = wstrtostr(p); - int i = atoi(q); - delete q; - return i; + PSTR q = wstrtostr(p); + int i = atoi(q); + delete[] q; + return i; } int 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 }; + 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; + 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; } int UTF32ToUTF16(int n, int *n1, int *n2) { - *n2 = -1; - if(n <= 0xFFFF) - { - *n1 = n; - if(n >= 0xD800 && n <= 0xDFFF) AddWarning(CWARN_UnicodeSurrogateUsed); - return CheckUTF16(*n1); - } + *n2 = -1; + if (n <= 0xFFFF) + { + *n1 = n; + if (n >= 0xD800 && n <= 0xDFFF) AddWarning(CWARN_UnicodeSurrogateUsed); + return 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; - if((n = CheckUTF16(*n1)) != CERR_None) return n; - return CheckUTF16(*n2); + 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; + if ((n = CheckUTF16(*n1)) != CERR_None) return n; + return CheckUTF16(*n2); } DWORD BuildVKDictionary(PFILE_KEYBOARD fk) // I3438 { DWORD i; size_t len = 0; - if(fk->cxVKDictionary == 0) return CERR_None; - for(i = 0; i < fk->cxVKDictionary; i++) + if (fk->cxVKDictionary == 0) return CERR_None; + for (i = 0; i < fk->cxVKDictionary; i++) { len += wcslen(fk->dpVKDictionary[i].szName) + 1; } PWSTR storeval = new WCHAR[len], p = storeval; - for(i = 0; i < fk->cxVKDictionary; i++) + for (i = 0; i < fk->cxVKDictionary; i++) { - wcscpy_s(p, len - (size_t)(p-storeval), fk->dpVKDictionary[i].szName); // I3481 + wcscpy_s(p, len - (size_t)(p - storeval), fk->dpVKDictionary[i].szName); // I3481 p = wcschr(p, 0); *p = ' '; p++; @@ -3354,103 +3371,103 @@ DWORD BuildVKDictionary(PFILE_KEYBOARD fk) // I3438 DWORD dwStoreID; DWORD msg = AddStore(fk, TSS_VKDICTIONARY, storeval, &dwStoreID); - delete storeval; + delete[] storeval; return msg; } int GetVKCode(PFILE_KEYBOARD fk, PWSTR p) // I3438 // TODO: Consolidate GetDeadKey and GetVKCode? { - DWORD i; + DWORD i; - for(i = 0; i < fk->cxVKDictionary; i++) - if(_wcsicmp(fk->dpVKDictionary[i].szName, p) == 0) - return i+VK__MAX+1; // 256 + for (i = 0; i < fk->cxVKDictionary; i++) + if (_wcsicmp(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]; + 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; - } - wcsncpy_s(fk->dpVKDictionary[fk->cxVKDictionary].szName, _countof(fk->dpVKDictionary[fk->cxVKDictionary].szName), p, SZMAX_VKDICTIONARYNAME); // I3481 - fk->dpVKDictionary[fk->cxVKDictionary].szName[SZMAX_VKDICTIONARYNAME-1] = 0; + } + wcsncpy_s(fk->dpVKDictionary[fk->cxVKDictionary].szName, _countof(fk->dpVKDictionary[fk->cxVKDictionary].szName), p, SZMAX_VKDICTIONARYNAME - 1); // I3481 + fk->dpVKDictionary[fk->cxVKDictionary].szName[SZMAX_VKDICTIONARYNAME - 1] = 0; - fk->cxVKDictionary++; - return fk->cxVKDictionary+VK__MAX; // 256-1 + fk->cxVKDictionary++; + return fk->cxVKDictionary + VK__MAX; // 256-1 } int GetDeadKey(PFILE_KEYBOARD fk, PWSTR p) { - DWORD i; + DWORD i; - for(i = 0; i < fk->cxDeadKeyArray; i++) - if(_wcsicmp(fk->dpDeadKeyArray[i].szName, p) == 0) - return i+1; + for (i = 0; i < fk->cxDeadKeyArray; i++) + if (_wcsicmp(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; - } - wcsncpy_s(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName, _countof(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName), p, SZMAX_DEADKEYNAME); // I3481 - fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName[SZMAX_DEADKEYNAME-1] = 0; + 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; + } + wcsncpy_s(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName, _countof(fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName), p, SZMAX_DEADKEYNAME); // I3481 + fk->dpDeadKeyArray[fk->cxDeadKeyArray].szName[SZMAX_DEADKEYNAME - 1] = 0; - fk->cxDeadKeyArray++; - return fk->cxDeadKeyArray; + fk->cxDeadKeyArray++; + return fk->cxDeadKeyArray; } void RecordDeadkeyNames(PFILE_KEYBOARD fk) { - WCHAR buf[SZMAX_DEADKEYNAME + 16]; - DWORD i; - for(i = 0; i < fk->cxDeadKeyArray; i++) - { - swprintf(buf, _countof(buf), L"%s%d %s", DEBUGSTORE_DEADKEY, i, fk->dpDeadKeyArray[i].szName); // I3481 - AddDebugStore(fk, buf); - } + WCHAR buf[SZMAX_DEADKEYNAME + 16]; + DWORD i; + for (i = 0; i < fk->cxDeadKeyArray; i++) + { + swprintf(buf, _countof(buf), L"%ls%d %ls", DEBUGSTORE_DEADKEY, (int)i, fk->dpDeadKeyArray[i].szName); // I3481 + AddDebugStore(fk, buf); + } } BOOL IsValidCallStore(PFILE_STORE fs) { - int i; - PWSTR 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; + int i; + PWSTR 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; + return i == 1; } HANDLE CreateTempFile() { - char szTempPathBuffer[MAX_PATH], szTempFileName[MAX_PATH]; // I3228 // I3510 - if(!GetTempPath(MAX_PATH, szTempPathBuffer)) return INVALID_HANDLE_VALUE; - if(!GetTempFileName(szTempPathBuffer, "kmx", 0, szTempFileName)) return INVALID_HANDLE_VALUE; // I3228 // I3510 - return CreateFile(szTempFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); + char szTempPathBuffer[MAX_PATH], szTempFileName[MAX_PATH]; // I3228 // I3510 + if (!GetTempPath(MAX_PATH, szTempPathBuffer)) return INVALID_HANDLE_VALUE; + if (!GetTempFileName(szTempPathBuffer, "kmx", 0, szTempFileName)) return INVALID_HANDLE_VALUE; // I3228 // I3510 + return CreateFile(szTempFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); } /////////////////// HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble) { - HANDLE hOutfile = CreateTempFile(); - if(hOutfile == INVALID_HANDLE_VALUE) // I3228 // I3510 + HANDLE hOutfile = CreateTempFile(); + if (hOutfile == INVALID_HANDLE_VALUE) // I3228 // I3510 { CloseHandle(hInfile); return INVALID_HANDLE_VALUE; } - PBYTE buf, p; - PWSTR outbuf, poutbuf; - DWORD len, len2; + PBYTE buf, p; + PWSTR outbuf, poutbuf; + DWORD len, len2; WCHAR prolog = 0xFEFF; WriteFile(hOutfile, &prolog, 2, &len2, NULL); @@ -3482,8 +3499,8 @@ HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble) // because we don't support HINT/INFO messages yet and we don't want // this to cause a blocking compile at this stage poutbuf = strtowstr((PSTR)buf); - WriteFile(hOutfile, poutbuf, (DWORD) wcslen(poutbuf) * 2, &len2, NULL); - delete poutbuf; + WriteFile(hOutfile, poutbuf, (DWORD)wcslen(poutbuf) * 2, &len2, NULL); + delete[] poutbuf; } else { WriteFile(hOutfile, outbuf, (DWORD)(INT_PTR)(poutbuf - outbuf) * 2, &len2, NULL); @@ -3492,10 +3509,10 @@ HANDLE UTF16TempFromUTF8(HANDLE hInfile, BOOL hasPreamble) } CloseHandle(hInfile); - delete buf; - delete outbuf; - SetFilePointer(hOutfile, 2, NULL, FILE_BEGIN); - return hOutfile; + delete[] buf; + delete[] outbuf; + SetFilePointer(hOutfile, 2, NULL, FILE_BEGIN); + return hOutfile; } extern "C" void __declspec(dllexport) Keyman_Diagnostic(int mode) { diff --git a/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp b/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp index 0fc760d222..6fc9c00b41 100644 --- a/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp +++ b/windows/src/developer/kmcmpdll/NamedCodeConstants.cpp @@ -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) diff --git a/windows/src/developer/kmcmpdll/kcframe.cpp b/windows/src/developer/kmcmpdll/kcframe.cpp index 2d41947135..2a704c9d43 100644 --- a/windows/src/developer/kmcmpdll/kcframe.cpp +++ b/windows/src/developer/kmcmpdll/kcframe.cpp @@ -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; } diff --git a/windows/src/developer/kmcmpdll/kmcmpdll.h b/windows/src/developer/kmcmpdll/kmcmpdll.h index 19c1a27de1..88535f93e5 100644 --- a/windows/src/developer/kmcmpdll/kmcmpdll.h +++ b/windows/src/developer/kmcmpdll/kmcmpdll.h @@ -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; \ No newline at end of file +extern int currentLine; diff --git a/windows/src/developer/kmcmpdll/versioning.cpp b/windows/src/developer/kmcmpdll/versioning.cpp index e1d7bfce5f..e805bfdef6 100644 --- a/windows/src/developer/kmcmpdll/versioning.cpp +++ b/windows/src/developer/kmcmpdll/versioning.cpp @@ -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); } diff --git a/windows/src/engine/keyman32/DebugEventTrace.cpp b/windows/src/engine/keyman32/DebugEventTrace.cpp index d9e8bbb4e3..3ff479a3a6 100644 --- a/windows/src/engine/keyman32/DebugEventTrace.cpp +++ b/windows/src/engine/keyman32/DebugEventTrace.cpp @@ -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" diff --git a/windows/src/engine/keyman32/K32_load.cpp b/windows/src/engine/keyman32/K32_load.cpp index cb8a131f11..fbdf59b308 100644 --- a/windows/src/engine/keyman32/K32_load.cpp +++ b/windows/src/engine/keyman32/K32_load.cpp @@ -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; } diff --git a/windows/src/engine/keyman32/Keyman32.cpp b/windows/src/engine/keyman32/Keyman32.cpp index f8e9aab9ce..1a3945b53e 100644 --- a/windows/src/engine/keyman32/Keyman32.cpp +++ b/windows/src/engine/keyman32/Keyman32.cpp @@ -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; diff --git a/windows/src/engine/keyman32/SharedBuffers.cpp b/windows/src/engine/keyman32/SharedBuffers.cpp index 1c52d03c6e..5b948d76fa 100644 --- a/windows/src/engine/keyman32/SharedBuffers.cpp +++ b/windows/src/engine/keyman32/SharedBuffers.cpp @@ -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"); diff --git a/windows/src/engine/keyman32/addins.cpp b/windows/src/engine/keyman32/addins.cpp index 1b0a65e7d2..6c7f5d0f28 100644 --- a/windows/src/engine/keyman32/addins.cpp +++ b/windows/src/engine/keyman32/addins.cpp @@ -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; } diff --git a/windows/src/engine/keyman32/appint/aiTIP.cpp b/windows/src/engine/keyman32/appint/aiTIP.cpp index d81f3b6030..bad49d28f1 100644 --- a/windows/src/engine/keyman32/appint/aiTIP.cpp +++ b/windows/src/engine/keyman32/appint/aiTIP.cpp @@ -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) diff --git a/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp b/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp index 4379e49971..b01227ca8f 100644 --- a/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp +++ b/windows/src/engine/keyman32/appint/aiWin2000Unicode.cpp @@ -303,7 +303,7 @@ BOOL AIWin2000Unicode::PostKeys() SendDebugMessageFormat(0, sdmAIDefault, 0, "App::PostKeys: sending input finished"); - delete pInputs; + delete[] pInputs; return TRUE; } diff --git a/windows/src/engine/keyman32/appint/appint.cpp b/windows/src/engine/keyman32/appint/appint.cpp index 0eace48036..018f3af806 100644 --- a/windows/src/engine/keyman32/appint/appint.cpp +++ b/windows/src/engine/keyman32/appint/appint.cpp @@ -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; } diff --git a/windows/src/engine/keyman32/calldll.cpp b/windows/src/engine/keyman32/calldll.cpp index c66cef968c..2db3fd6643 100644 --- a/windows/src/engine/keyman32/calldll.cpp +++ b/windows/src/engine/keyman32/calldll.cpp @@ -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; diff --git a/windows/src/engine/keyman32/k32_dbg.cpp b/windows/src/engine/keyman32/k32_dbg.cpp index d19a6cfbc5..b58eb8df85 100644 --- a/windows/src/engine/keyman32/k32_dbg.cpp +++ b/windows/src/engine/keyman32/k32_dbg.cpp @@ -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); } diff --git a/windows/src/engine/keyman32/k32_tsf.cpp b/windows/src/engine/keyman32/k32_tsf.cpp index af888eb14d..9a1d404174 100644 --- a/windows/src/engine/keyman32/k32_tsf.cpp +++ b/windows/src/engine/keyman32/k32_tsf.cpp @@ -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); diff --git a/windows/src/engine/keyman32/keybd_shift.cpp b/windows/src/engine/keyman32/keybd_shift.cpp index 5c94bf7041..37eeeb80f9 100644 --- a/windows/src/engine/keyman32/keybd_shift.cpp +++ b/windows/src/engine/keyman32/keybd_shift.cpp @@ -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; diff --git a/windows/src/engine/keyman32/keyboardoptions.cpp b/windows/src/engine/keyman32/keyboardoptions.cpp index 1e0e0a8511..e0964cfd97 100644 --- a/windows/src/engine/keyman32/keyboardoptions.cpp +++ b/windows/src/engine/keyman32/keyboardoptions.cpp @@ -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; diff --git a/windows/src/engine/keyman32/kmhook_getmessage.cpp b/windows/src/engine/keyman32/kmhook_getmessage.cpp index a20b98888f..f58ac74f59 100644 --- a/windows/src/engine/keyman32/kmhook_getmessage.cpp +++ b/windows/src/engine/keyman32/kmhook_getmessage.cpp @@ -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); -} \ No newline at end of file +} diff --git a/windows/src/engine/keyman32/kmprocess.cpp b/windows/src/engine/keyman32/kmprocess.cpp index d1a3828f6b..d1f76e1b61 100644 --- a/windows/src/engine/keyman32/kmprocess.cpp +++ b/windows/src/engine/keyman32/kmprocess.cpp @@ -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; } diff --git a/windows/src/engine/keyman32/selectkeyboard.cpp b/windows/src/engine/keyman32/selectkeyboard.cpp index b732f4daa2..e207b5eb64 100644 --- a/windows/src/engine/keyman32/selectkeyboard.cpp +++ b/windows/src/engine/keyman32/selectkeyboard.cpp @@ -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 diff --git a/windows/src/engine/keyman32/serialkeyeventserver.cpp b/windows/src/engine/keyman32/serialkeyeventserver.cpp index a7682374f1..bf10694176 100644 --- a/windows/src/engine/keyman32/serialkeyeventserver.cpp +++ b/windows/src/engine/keyman32/serialkeyeventserver.cpp @@ -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; } } diff --git a/windows/src/engine/keyman32/versioninfo.cpp b/windows/src/engine/keyman32/versioninfo.cpp index da906c98cf..07734f58b5 100644 --- a/windows/src/engine/keyman32/versioninfo.cpp +++ b/windows/src/engine/keyman32/versioninfo.cpp @@ -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) diff --git a/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas b/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas index d7a0791710..ead129c382 100644 --- a/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas +++ b/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas @@ -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, diff --git a/windows/src/engine/kmtip/debug.cpp b/windows/src/engine/kmtip/debug.cpp index 4ba02ede37..eaa8578b5f 100644 --- a/windows/src/engine/kmtip/debug.cpp +++ b/windows/src/engine/kmtip/debug.cpp @@ -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"); diff --git a/windows/src/engine/kmtip/inserttext.cpp b/windows/src/engine/kmtip/inserttext.cpp index ad329ec6a6..4ed11a2309 100644 --- a/windows/src/engine/kmtip/inserttext.cpp +++ b/windows/src/engine/kmtip/inserttext.cpp @@ -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 diff --git a/windows/src/engine/kmtip/kmkey.cpp b/windows/src/engine/kmtip/kmkey.cpp index 0271a86172..aacb6cf768 100644 --- a/windows/src/engine/kmtip/kmkey.cpp +++ b/windows/src/engine/kmtip/kmkey.cpp @@ -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) { diff --git a/windows/src/engine/kmtip/kmtip.cpp b/windows/src/engine/kmtip/kmtip.cpp index 146603c78d..fb9194816b 100644 --- a/windows/src/engine/kmtip/kmtip.cpp +++ b/windows/src/engine/kmtip/kmtip.cpp @@ -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; -} \ No newline at end of file +} diff --git a/windows/src/engine/kmtip/register.cpp b/windows/src/engine/kmtip/register.cpp index f0e4fb8af2..0102432ea4 100644 --- a/windows/src/engine/kmtip/register.cpp +++ b/windows/src/engine/kmtip/register.cpp @@ -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 diff --git a/windows/src/engine/mcompile/mc_import_rules.cpp b/windows/src/engine/mcompile/mc_import_rules.cpp index 826dd7f621..403cbcd7f1 100644 --- a/windows/src/engine/mcompile/mc_import_rules.cpp +++ b/windows/src/engine/mcompile/mc_import_rules.cpp @@ -462,7 +462,7 @@ bool ImportRules(WCHAR *kbid, LPKEYBOARD kp, std::vector *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 *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 *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 diff --git a/windows/src/engine/mcompile/mc_kmxfile.cpp b/windows/src/engine/mcompile/mc_kmxfile.cpp index c20f8053d0..99db7daf05 100644 --- a/windows/src/engine/mcompile/mc_kmxfile.cpp +++ b/windows/src/engine/mcompile/mc_kmxfile.cpp @@ -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; diff --git a/windows/src/engine/mcompile/mc_savekeyboard.cpp b/windows/src/engine/mcompile/mc_savekeyboard.cpp index bd8ac1beeb..35acde8b64 100644 --- a/windows/src/engine/mcompile/mc_savekeyboard.cpp +++ b/windows/src/engine/mcompile/mc_savekeyboard.cpp @@ -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; } diff --git a/windows/src/engine/mcompile/mc_unicode.cpp b/windows/src/engine/mcompile/mc_unicode.cpp index 93293326cd..bc86536f69 100644 --- a/windows/src/engine/mcompile/mc_unicode.cpp +++ b/windows/src/engine/mcompile/mc_unicode.cpp @@ -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; } diff --git a/windows/src/engine/mcompile/mcompile.cpp b/windows/src/engine/mcompile/mcompile.cpp index c09a458fa8..06e79bd44c 100644 --- a/windows/src/engine/mcompile/mcompile.cpp +++ b/windows/src/engine/mcompile/mcompile.cpp @@ -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); diff --git a/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas b/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas index 539ce1db3e..47efb21066 100644 --- a/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas +++ b/windows/src/global/delphi/general/Keyman.System.CanonicalLanguageCodeUtils.pas @@ -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 - /// ///Find a language code with appropriate script and region subtags /// diff --git a/windows/src/global/vc/keymansentry.cpp b/windows/src/global/vc/keymansentry.cpp index 090d0586af..f2a37332e2 100644 --- a/windows/src/global/vc/keymansentry.cpp +++ b/windows/src/global/vc/keymansentry.cpp @@ -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();