From c3458d040cfe8950db7253367d88f78f06b9ff18 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 1 Jun 2023 15:11:38 +0700 Subject: [PATCH] refactor(developer): move filename consistency check to kmc kmcmplib no longer has any filesystem access, so it cannot verify if a referenced filename in a source file has the same case as the actual filename on disk (a risk when moving projects between platforms). So I opted to move this to the `loadFile` callback in kmc, which is the only place where filesystem is actually accessed, and added corresponding unit test. Small additional fixes here: 1. Move from `Buffer` to `Uint8Array` in all kmc-* modules, so that we remove that barrier to running on web. 2. Use `callbacks.loadFile` instead of `callbacks.fs.readFileSync`, so that we can be sure to run the filename consistency check. 3. Fixed kps parser silently swallowing xml errors on load. 4. Added silent mode to NodeCompilerCallbacks so we could cleanly test the new filename consistency hint. 5. Noted a location where we still have NodeJS deps in kmc-ldml. --- common/web/types/src/kpj/kpj-file-reader.ts | 4 +- common/web/types/src/kvk/kvks-file-reader.ts | 4 +- .../ldml-keyboard/ldml-keyboard-xml-reader.ts | 11 +- .../web/types/src/util/compiler-interfaces.ts | 6 +- .../test/helpers/TestCompilerCallbacks.ts | 2 +- .../src/common/include/kmn_compiler_errors.h | 4 +- .../src/common/web/test-helpers/index.ts | 4 +- developer/src/kmc-kmn/test/test-messages.ts | 3 +- .../kmc-package/src/compiler/kmp-compiler.ts | 27 ++++- .../kmc/src/messages/NodeCompilerCallbacks.ts | 48 +++++++- developer/src/kmc/src/messages/messages.ts | 6 +- .../hint_filename_has_differing_case.kmn | 6 + developer/src/kmc/test/test-messages.ts | 71 +++++++++++ .../kmcmplib/src/CheckFilenameConsistency.cpp | 112 ------------------ .../kmcmplib/src/CheckFilenameConsistency.h | 9 -- developer/src/kmcmplib/src/CompMsg.cpp | 2 - .../kmcmplib/src/CompileKeyboardBuffer.cpp | 6 - developer/src/kmcmplib/src/Compiler.cpp | 14 --- .../src/kmcmplib/src/NamedCodeConstants.cpp | 5 - developer/src/kmcmplib/src/meson.build | 16 +-- 20 files changed, 174 insertions(+), 186 deletions(-) create mode 100644 developer/src/kmc/test/fixtures/invalid-keyboards/hint_filename_has_differing_case.kmn delete mode 100644 developer/src/kmcmplib/src/CheckFilenameConsistency.cpp delete mode 100644 developer/src/kmcmplib/src/CheckFilenameConsistency.h diff --git a/common/web/types/src/kpj/kpj-file-reader.ts b/common/web/types/src/kpj/kpj-file-reader.ts index 5f768c54f1..21e92c975b 100644 --- a/common/web/types/src/kpj/kpj-file-reader.ts +++ b/common/web/types/src/kpj/kpj-file-reader.ts @@ -27,8 +27,8 @@ export class KPJFileReader { return data as KPJFile; } - public validate(source: KPJFile, schemaBuffer: Buffer): void { - const schema = JSON.parse(schemaBuffer.toString('utf8')); + public validate(source: KPJFile, schemaBuffer: Uint8Array): void { + const schema = JSON.parse(new TextDecoder().decode(schemaBuffer)); const ajv = new Ajv(); if(!ajv.validate(schema, source)) { throw new Error(ajv.errorsText()); diff --git a/common/web/types/src/kvk/kvks-file-reader.ts b/common/web/types/src/kvk/kvks-file-reader.ts index 184c162210..13c6c8716c 100644 --- a/common/web/types/src/kvk/kvks-file-reader.ts +++ b/common/web/types/src/kvk/kvks-file-reader.ts @@ -68,8 +68,8 @@ export default class KVKSFileReader { } } - public validate(source: KVKSourceFile, schemaBuffer: Buffer): void { - const schema = JSON.parse(schemaBuffer.toString('utf8')); + public validate(source: KVKSourceFile, schemaBuffer: Uint8Array): void { + const schema = JSON.parse(new TextDecoder().decode(schemaBuffer)); const ajv = new Ajv(); if(!ajv.validate(schema, source)) { throw new Error(ajv.errorsText()); diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts index 35d7f62795..bc2779ab8e 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts @@ -7,6 +7,7 @@ import { CompilerCallbacks } from '../util/compiler-interfaces.js'; import { constants } from '@keymanapp/ldml-keyboard-constants'; import { CommonTypesMessages } from '../util/common-events.js'; import { LDMLKeyboardTestDataXMLSourceFile, LKTTest, LKTTests } from './ldml-keyboard-testdata-xml.js'; +import { fileURLToPath } from 'url'; interface NameAndProps { '$'?: any; // content @@ -21,9 +22,9 @@ export default class LDMLKeyboardXMLSourceFileReader { this.callbacks = callbacks; } - readImportFile(version: string, subpath: string): Buffer { - // TODO-LDML: sanitize input string - let importPath = new URL(`../import/${version}/${subpath}`, import.meta.url); + readImportFile(version: string, subpath: string): Uint8Array { + // TODO-LDML: use this.callbacks.resolveFilename to get the actual path + let importPath = fileURLToPath(new URL(`../import/${version}/${subpath}`, import.meta.url)); return this.callbacks.loadFile(importPath); } @@ -201,8 +202,8 @@ export default class LDMLKeyboardXMLSourceFileReader { /** * @returns true if valid, false if invalid */ - public validate(source: LDMLKeyboardXMLSourceFile | LDMLKeyboardTestDataXMLSourceFile, schemaSource: Buffer): boolean { - const schema = JSON.parse(schemaSource.toString('utf8')); + public validate(source: LDMLKeyboardXMLSourceFile | LDMLKeyboardTestDataXMLSourceFile, schemaSource: Uint8Array): boolean { + const schema = JSON.parse(new TextDecoder().decode(schemaSource)); const ajv = new Ajv(); if(!ajv.validate(schema, source)) { for (let err of ajv.errors) { diff --git a/common/web/types/src/util/compiler-interfaces.ts b/common/web/types/src/util/compiler-interfaces.ts index 849e945321..d3932b7bfa 100644 --- a/common/web/types/src/util/compiler-interfaces.ts +++ b/common/web/types/src/util/compiler-interfaces.ts @@ -120,13 +120,11 @@ export interface CompilerFileSystemCallbacks { export interface CompilerCallbacks { /** * Attempt to load a file. Return falsy if not found. - * TODO: accept only string * TODO: never return falsy, just throw if not found? - * TODO: Buffer is Node-only. * @param baseFilename * @param filename */ - loadFile(filename: string | URL): Buffer; + loadFile(filename: string): Uint8Array; get path(): CompilerPathCallbacks; get fs(): CompilerFileSystemCallbacks; @@ -138,7 +136,7 @@ export interface CompilerCallbacks { */ resolveFilename(baseFilename: string, filename: string): string; - loadSchema(schema: CompilerSchema): Buffer; + loadSchema(schema: CompilerSchema): Uint8Array; reportMessage(event: CompilerEvent): void; debug(msg: string): void; }; diff --git a/common/web/types/test/helpers/TestCompilerCallbacks.ts b/common/web/types/test/helpers/TestCompilerCallbacks.ts index 596a731d58..8316264a77 100644 --- a/common/web/types/test/helpers/TestCompilerCallbacks.ts +++ b/common/web/types/test/helpers/TestCompilerCallbacks.ts @@ -42,7 +42,7 @@ export class TestCompilerCallbacks implements CompilerCallbacks { return resolveFilename(baseFilename, filename); } - loadFile(filename: string | URL): Buffer { + loadFile(filename: string): Uint8Array { // TODO: error management, does it belong here? try { return loadFile(filename); diff --git a/developer/src/common/include/kmn_compiler_errors.h b/developer/src/common/include/kmn_compiler_errors.h index 6cfae03fc9..31c5faf0c7 100644 --- a/developer/src/common/include/kmn_compiler_errors.h +++ b/developer/src/common/include/kmn_compiler_errors.h @@ -224,8 +224,8 @@ #define CWARN_KeyShouldIncludeNCaps 0x000020AD #define CHINT_UnreachableRule 0x000010AE -#define CHINT_FilenameHasDifferingCase 0x000010AF -#define CWARN_MissingFile 0x000020B0 +#define CHINT_FilenameHasDifferingCase 0x000010AF // only used in kmcmpdll +#define CWARN_MissingFile 0x000020B0 // only used in kmcmpdll #define CERR_BufferOverflow 0x000080C0 #define CERR_Break 0x000080C1 diff --git a/developer/src/common/web/test-helpers/index.ts b/developer/src/common/web/test-helpers/index.ts index 7f34107dc9..0a85287d3d 100644 --- a/developer/src/common/web/test-helpers/index.ts +++ b/developer/src/common/web/test-helpers/index.ts @@ -36,7 +36,7 @@ export class TestCompilerCallbacks implements CompilerCallbacks { /* CompilerCallbacks */ - loadFile(filename: string | URL): Buffer { + loadFile(filename: string): Uint8Array { try { return fs.readFileSync(filename); } catch(e) { @@ -77,7 +77,7 @@ export class TestCompilerCallbacks implements CompilerCallbacks { this.messages.push(event); } - loadSchema(schema: CompilerSchema): Buffer { + loadSchema(schema: CompilerSchema): Uint8Array { return fs.readFileSync(new URL(SCHEMA_BASE + schema + '.schema.json', import.meta.url)); } diff --git a/developer/src/kmc-kmn/test/test-messages.ts b/developer/src/kmc-kmn/test/test-messages.ts index dce0c2477d..4d724daaf5 100644 --- a/developer/src/kmc-kmn/test/test-messages.ts +++ b/developer/src/kmc-kmn/test/test-messages.ts @@ -1,4 +1,5 @@ import 'mocha'; +import path from 'path'; import { assert } from 'chai'; import { CompilerMessages } from '../src/compiler/messages.js'; import { TestCompilerCallbacks, verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; @@ -26,7 +27,7 @@ describe('CompilerMessages', function () { assert(compiler.verifyInitialized()); const kmnPath = makePathToFixture(...fixture); - const outfile = callbacks.path.basename(kmnPath, '.kmn') + '.kmx'; + const outfile = path.basename(kmnPath, '.kmn') + '.kmx'; // Note: throwing away compile results (just to memory) compiler.runCompiler(kmnPath, outfile, {saveDebug: true, shouldAddCompilerVersion: false}); diff --git a/developer/src/kmc-package/src/compiler/kmp-compiler.ts b/developer/src/kmc-package/src/compiler/kmp-compiler.ts index b660641df9..198a1ef2de 100644 --- a/developer/src/kmc-package/src/compiler/kmp-compiler.ts +++ b/developer/src/kmc-package/src/compiler/kmp-compiler.ts @@ -16,7 +16,12 @@ export class KmpCompiler { public transformKpsToKmpObject(kpsFilename: string): KmpJsonFile.KmpJsonFile { // Load the KPS data from XML as JS structured data. - const data = this.callbacks.fs.readFileSync(kpsFilename, 'utf-8'); + const buffer = this.callbacks.loadFile(kpsFilename); + if(!buffer) { + this.callbacks.reportMessage(CompilerMessages.Error_FileDoesNotExist({filename: kpsFilename})); + return null; + } + const data = new TextDecoder().decode(buffer); const kpsPackage = (() => { let a: KpsFile.KpsPackage; @@ -24,7 +29,8 @@ export class KmpCompiler { tagNameProcessors: [xml2js.processors.firstCharLowerCase], explicitArray: false }); - parser.parseString(data, (e: unknown, r: unknown) => { a = r as KpsFile.KpsPackage }); + // TODO: add unit test for xml errors parsing .kps file + parser.parseString(data, (e: unknown, r: unknown) => { if(e) throw e; a = r as KpsFile.KpsPackage }); return a; })(); @@ -284,9 +290,20 @@ export class KmpCompiler { * we want that to remain the responsibility of the keyboard compiler, so we'll warn the * few users who are still doing this */ - private warnIfKvkFileIsNotBinary(filename: string, data: Buffer) { - // TODO: Buffer is not available on web - if(filename.match(/\.kvk$/) && data.compare(Buffer.from(KvkFile.KVK_HEADER_IDENTIFIER_BYTES), 0, 3, 0, 3) != 0) { + private warnIfKvkFileIsNotBinary(filename: string, data: Uint8Array) { + if(!filename.match(/\.kvk$/)) { + return; + } + + if(data.byteLength < 4) { + // TODO: Not a valid .kvk file; should we be reporting this? + return; + } + + if(data[0] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[0] || + data[1] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[1] || + data[2] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[2] || + data[3] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[3]) { this.callbacks.reportMessage(CompilerMessages.Warn_FileIsNotABinaryKvkFile({filename: filename})); } } diff --git a/developer/src/kmc/src/messages/NodeCompilerCallbacks.ts b/developer/src/kmc/src/messages/NodeCompilerCallbacks.ts index ceae18c4c5..f8232cde5f 100644 --- a/developer/src/kmc/src/messages/NodeCompilerCallbacks.ts +++ b/developer/src/kmc/src/messages/NodeCompilerCallbacks.ts @@ -1,14 +1,52 @@ import * as fs from 'fs'; import * as path from 'path'; import { CompilerCallbacks, CompilerSchema, CompilerEvent, compilerErrorSeverityName, CompilerPathCallbacks, CompilerFileSystemCallbacks } from '@keymanapp/common-types'; +import { InfrastructureMessages } from './messages.js'; /** * Concrete implementation for CLI use */ +// TODO: Make a common class for all the CompilerCallbacks implementations + export class NodeCompilerCallbacks implements CompilerCallbacks { - // TODO: REMOVE! - loadFile(filename: string | URL): Buffer { + /* NodeCompilerCallbacks */ + + messages: CompilerEvent[] = []; + silent: boolean; + + constructor(silent?: boolean) { + this.silent = !!silent; + } + + clear() { + this.messages = []; + } + + hasMessage(code: number): boolean { + return this.messages.find((item) => item.code == code) === undefined ? false : true; + } + + private verifyFilenameConsistency(originalFilename: string): void { + if(fs.existsSync(originalFilename)) { + // Note, we only check this if the file exists, because + // if it is not found, that will be returned as an error + // from loadFile anyway. + const filename = fs.realpathSync(originalFilename); + const nativeFilename = fs.realpathSync.native(filename); + if(filename != nativeFilename) { + this.reportMessage(InfrastructureMessages.Hint_FilenameHasDifferingCase({ + reference: originalFilename, + filename: nativeFilename + })); + } + } + } + + /* CompilerCallbacks */ + + loadFile(filename: string): Uint8Array { + this.verifyFilenameConsistency(filename); try { return fs.readFileSync(filename); } catch (e) { @@ -29,6 +67,10 @@ export class NodeCompilerCallbacks implements CompilerCallbacks { } reportMessage(event: CompilerEvent): void { + this.messages.push(event); + if(this.silent) { + return; + } const code = event.code.toString(16); if(event.line) { console.log(`${compilerErrorSeverityName(event.code)} ${code} [${event.line}]: ${event.message}`); @@ -41,7 +83,7 @@ export class NodeCompilerCallbacks implements CompilerCallbacks { console.debug(msg); } - loadSchema(schema: CompilerSchema) { + loadSchema(schema: CompilerSchema): Uint8Array { let schemaPath = new URL('../util/' + schema + '.schema.json', import.meta.url); return fs.readFileSync(schemaPath); } diff --git a/developer/src/kmc/src/messages/messages.ts b/developer/src/kmc/src/messages/messages.ts index 1f1761e715..358a59406b 100644 --- a/developer/src/kmc/src/messages/messages.ts +++ b/developer/src/kmc/src/messages/messages.ts @@ -2,7 +2,7 @@ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m const Namespace = CompilerErrorNamespace.Infrastructure; const SevInfo = CompilerErrorSeverity.Info | Namespace; -// const SevHint = CompilerErrorSeverity.Hint | Namespace; +const SevHint = CompilerErrorSeverity.Hint | Namespace; // const SevWarn = CompilerErrorSeverity.Warn | Namespace; const SevError = CompilerErrorSeverity.Error | Namespace; const SevFatal = CompilerErrorSeverity.Fatal | Namespace; @@ -39,5 +39,9 @@ export class InfrastructureMessages { static Error_InvalidProjectFile = (o:{message:string}) => m(this.ERROR_InvalidProjectFile, `Project file is not valid: ${o.message}`); static ERROR_InvalidProjectFile = SevError | 0x0008; + + static Hint_FilenameHasDifferingCase = (o:{reference:string, filename:string}) => m(this.HINT_FilenameHasDifferingCase, + `File ${o.filename} differs in case from reference ${o.reference}; this will fail on platforms with case-sensitive filesystems.`); + static HINT_FilenameHasDifferingCase = SevHint | 0x0009; } diff --git a/developer/src/kmc/test/fixtures/invalid-keyboards/hint_filename_has_differing_case.kmn b/developer/src/kmc/test/fixtures/invalid-keyboards/hint_filename_has_differing_case.kmn new file mode 100644 index 0000000000..5792016e10 --- /dev/null +++ b/developer/src/kmc/test/fixtures/invalid-keyboards/hint_filename_has_differing_case.kmn @@ -0,0 +1,6 @@ +store(&name) 'hint_filename_has_differing_case' +store(&version) '7.0' + +begin unicode > use(main) + +group(main) using keys diff --git a/developer/src/kmc/test/test-messages.ts b/developer/src/kmc/test/test-messages.ts index 7b591ad72d..045718075d 100644 --- a/developer/src/kmc/test/test-messages.ts +++ b/developer/src/kmc/test/test-messages.ts @@ -1,9 +1,80 @@ import 'mocha'; +import { assert } from 'chai'; import { InfrastructureMessages } from '../src/messages/messages.js'; import { verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; +import { makePathToFixture } from './helpers/index.js'; +import { NodeCompilerCallbacks } from '../src/messages/NodeCompilerCallbacks.js'; describe('InfrastructureMessages', function () { it('should have a valid InfrastructureMessages object', function() { return verifyCompilerMessagesObject(InfrastructureMessages); }); + + // + // Message tests + // + + /* + TODO: + + let callbacks = new TestCompilerCallbacks(); + + async function testForMessage(context: Mocha.Context, fixture: string[], messageId?: number) { + context.timeout(10000); + + callbacks.clear(); + + const builder = new BuildKmnKeyboard(); + const path = makePathToFixture(...fixture); + let result = await builder.build(path, callbacks, { + compilerVersion: false, + compilerWarningsAsErrors: true, + debug: false, + warnDeprecatedCode: true, + }); + + if(messageId) { + assert.isTrue(callbacks.hasMessage(messageId), `messageId ${messageId.toString(16)} not generated, instead got: `+JSON.stringify(callbacks.messages,null,2)); + assert.lengthOf(callbacks.messages, 1); + } else { + assert.lengthOf(callbacks.messages, 0, `messages should be empty, but instead got: `+JSON.stringify(callbacks.messages,null,2)); + assert.isTrue(result); + } + } + + // ERROR_FileDoesNotExist + + it('should generate ERROR_FileDoesNotExist if a file does not exist', async function() { + await testForMessage(this, ['invalid-keyboards', 'error_file_does_not_exist.kmn'], CompilerMessages.ERROR_FileDoesNotExist); + }); + + // ERROR_FileTypeNotRecognized + + it('should generate ERROR_FileTypeNotRecognized if a file is not a recognized type', async function() { + await testForMessage(this, ['invalid-keyboards', 'error_file_type_not_recognized.xxx'], CompilerMessages.ERROR_FileTypeNotRecognized); + }); + + // ERROR_OutFileNotValidForProjects + + it('should generate ERROR_OutFileNotValidForProjects if an output file is specified for a project build', async function() { + await testForMessage(this, ['invalid-keyboards', 'error_out_file_not_valid_for_projects.kpj'], CompilerMessages.ERROR_OutFileNotValidForProjects); + }); + + // ERROR_InvalidProjectFile + + it('should generate ERROR_InvalidProjectFile if a project file is invalid', async function() { + await testForMessage(this, ['invalid-keyboards', 'error_invalid_project_file.kpj'], CompilerMessages.ERROR_InvalidProjectFile); + }); + */ + + // HINT_FilenameHasDifferingCase + + it('should generate HINT_FilenameHasDifferingCase if a referenced file has differing case', async function() { + // This message is generated by NodeCompilerCallbacks, because that's where the filesystem is visible, + // so we can't use our usual testForMessage pattern. + const ncb = new NodeCompilerCallbacks(true); + ncb.loadFile(makePathToFixture('invalid-keyboards', 'Hint_Filename_Has_Differing_Case.kmn')); + assert.isTrue(ncb.hasMessage(InfrastructureMessages.HINT_FilenameHasDifferingCase), + `HINT_FilenameHasDifferingCase not generated, instead got: `+JSON.stringify(ncb.messages,null,2)); + }); }); diff --git a/developer/src/kmcmplib/src/CheckFilenameConsistency.cpp b/developer/src/kmcmplib/src/CheckFilenameConsistency.cpp deleted file mode 100644 index 6d113d116b..0000000000 --- a/developer/src/kmcmplib/src/CheckFilenameConsistency.cpp +++ /dev/null @@ -1,112 +0,0 @@ - -#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING 1 -#include "pch.h" -#include "compfile.h" -#include -#include "kmcmplib.h" -#include -#include "CheckFilenameConsistency.h" -#include "kmx_u16.h" - -#ifdef _MSC_VER -#include -#endif - - - -KMX_DWORD CheckFilenameConsistency( KMX_CHAR const * Filename, bool ReportMissingFile) { - PKMX_WCHAR WFilename = strtowstr(( KMX_CHAR *)Filename); - KMX_DWORD const result = CheckFilenameConsistency(WFilename, ReportMissingFile); - delete WFilename; - return result; -} - -KMX_DWORD CheckFilenameConsistency(KMX_WCHAR const * Filename, bool ReportMissingFile) { - // TODO: we no longer have filesystem access here. We could move this check to - // kmc itself, and make it consistent across all compilers that use the same - // loader callback -- see #8883 - return CERR_None; - -#if 0 - // not ready yet: needs more attention-> common includes for non-Windows platforms - KMX_WCHAR Name[260]; // TODO: fixed buffer sizes bad - - - if (IsRelativePath(Filename)) { - PKMX_WCHAR WCompileDir = strtowstr(kmcmp::CompileDir); - u16ncpy(Name, WCompileDir, _countof(Name)); // I3481 - u16ncat(Name, Filename, _countof(Name)); // I3481 - delete[] WCompileDir; - } else { - u16ncpy(Name, Filename, _countof(Name)); // I3481 - } - -#ifndef _MSC_VER - // Filename consistency only needs to be checked on Windows, because other - // platforms are going to fail if the filename is inconsistent anyway! - if(!kmcmp_FileExists(Name)) { - if (ReportMissingFile) { - u16cpy(ErrExtraW, u"referenced file '"); - u16ncat(ErrExtraW, Filename, 256); - u16ncat(ErrExtraW, u"'", 256); - strcpy(ErrExtraLIB, string_from_u16string(ErrExtraW).c_str()); - AddWarning(CWARN_MissingFile); - } - return CERR_None; - } - return CERR_None; -#else - _wfinddata_t fi; - intptr_t n; - if ((n = _wfindfirst((const wchar_t*) Name, &fi)) == -1) { - if (ReportMissingFile) { - sprintf(ErrExtraLIB, "referenced file '%ls'", (wchar_t*) Filename); - AddWarning(CWARN_MissingFile); - } - return CERR_None; - } - - _findclose(n); - - KMX_WCHAR FName[_MAX_FNAME], Ext[_MAX_EXT]; - wchar_t WChName[_MAX_PATH]; - _wsplitpath_s((const wchar_t*)Filename, nullptr, 0, nullptr, 0, (wchar_t*) FName, _MAX_FNAME, (wchar_t*) Ext, _MAX_EXT); - _wmakepath_s(WChName, _MAX_PATH, nullptr, nullptr, (const wchar_t*) FName, (const wchar_t*) Ext); - if (wcscmp(WChName, fi.name) != 0) { - sprintf(ErrExtraLIB, "reference '%ls' does not match actual filename '%ls'", WChName, fi.name); - - AddWarning(CHINT_FilenameHasDifferingCase); - - } -#endif - - return CERR_None; -#endif -} - -KMX_DWORD CheckFilenameConsistencyForCalls(PFILE_KEYBOARD fk) { - // call() statements depend on a fairly ugly hack for js, - // where store(DllFunction) "my.dll:func" will look for a - // file called function.call_js. ( or should this be func.call_js ? ) - // This is ripe for rewrite! - // But let's check what we have anyway - - PFILE_STORE sp; - KMX_DWORD i, msg; - for (i = 0, sp = fk->dpStoreArray; i < fk->cxStoreArray; i++, sp++) { - if (!sp->fIsCall) continue; - - const std::u16string callsite(sp->dpString); - const auto colon = callsite.find(':'); - if (colon == std::u16string::npos) continue; - - auto func1 = callsite.substr(colon + 1); - std::u16string str_js(u".call_js"); - std::u16string func = func1+ str_js; - - if ((msg = CheckFilenameConsistency(func.c_str(), FALSE)) != CERR_None) { - return msg; - } - } - return CERR_None; -} diff --git a/developer/src/kmcmplib/src/CheckFilenameConsistency.h b/developer/src/kmcmplib/src/CheckFilenameConsistency.h deleted file mode 100644 index eba8f2d8bf..0000000000 --- a/developer/src/kmcmplib/src/CheckFilenameConsistency.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "compfile.h" -#include "kmcmplib.h" - -KMX_DWORD CheckFilenameConsistencyForCalls(PFILE_KEYBOARD fk); -KMX_DWORD CheckFilenameConsistency(KMX_CHAR const * Filename, bool ReportMissingFile); -KMX_DWORD CheckFilenameConsistency(KMX_WCHAR const * Filename, bool ReportMissingFile); - diff --git a/developer/src/kmcmplib/src/CompMsg.cpp b/developer/src/kmcmplib/src/CompMsg.cpp index 2fa0d68322..dd41336a0e 100644 --- a/developer/src/kmcmplib/src/CompMsg.cpp +++ b/developer/src/kmcmplib/src/CompMsg.cpp @@ -111,7 +111,6 @@ const struct CompilerError CompilerErrors[] = { { CERR_DuplicateStore , "A store with this name has already been defined."}, { CERR_RepeatedBegin , "Begin has already been set"}, - { CHINT_FilenameHasDifferingCase , "Casing differences may fail on some platforms: "}, { CHINT_UnreachableRule , "This rule will never be matched as another rule takes precedence"}, { CWARN_TooManyWarnings , "Too many warnings or errors"}, @@ -142,7 +141,6 @@ const struct CompilerError CompilerErrors[] = { { CWARN_NulNotFirstStatementInContext , "nul must be the first statement in the context"}, { CWARN_IfShouldBeAtStartOfContext , "if, platform and baselayout should be at start of context (after nul, if present)"}, { CWARN_KeyShouldIncludeNCaps , "Other rules which reference this key include CAPS or NCAPS modifiers, so this rule must include NCAPS modifier to avoid inconsistent matches"}, - { CWARN_MissingFile , "The referenced file could not be found: "}, { 0, nullptr } }; diff --git a/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp b/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp index c932f68a4f..e90938f18a 100644 --- a/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp +++ b/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp @@ -1,7 +1,6 @@ #include "pch.h" #include #include "kmcmplib.h" -#include "CheckFilenameConsistency.h" #include "CheckNCapsConsistency.h" #include "DeprecationChecks.h" #include "versioning.h" @@ -143,11 +142,6 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk) return FALSE; } - if ((msg = CheckFilenameConsistencyForCalls(fk)) != CERR_None) { - AddCompileError(msg); - return FALSE; - } - delete str; if (!kmcmp::CheckKeyboardFinalVersion(fk)) { diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 49484b1acc..b862cb7d9f 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -97,7 +97,6 @@ #include #include -#include "CheckFilenameConsistency.h" #include "UnreachableRules.h" #include "CheckForDuplicates.h" #include "kmx_u16.h" @@ -1045,10 +1044,6 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE delete[] sp->dpString; sp->dpString = q; - - if ((msg = CheckFilenameConsistency( (sp->dpString), FALSE)) != CERR_None) { - return msg; - } } break; case TSS_KMW_RTL: @@ -1059,16 +1054,10 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE case TSS_KMW_HELPFILE: case TSS_KMW_EMBEDJS: VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); - if ((msg = CheckFilenameConsistency(sp->dpString, FALSE)) != CERR_None) { - return msg; - } break; case TSS_KMW_EMBEDCSS: VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyEmbedCSS); - if ((msg = CheckFilenameConsistency(sp->dpString, FALSE)) != CERR_None) { - return msg; - } break; case TSS_TARGETS: // I4504 @@ -1118,9 +1107,6 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE case TSS_LAYOUTFILE: // I3483 VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyLayoutFile); // I4140 - if ((msg = CheckFilenameConsistency(sp->dpString, FALSE)) != CERR_None) { - return msg; - } // Used by KMW compiler break; diff --git a/developer/src/kmcmplib/src/NamedCodeConstants.cpp b/developer/src/kmcmplib/src/NamedCodeConstants.cpp index 30091b7cb8..a8af8fa783 100644 --- a/developer/src/kmcmplib/src/NamedCodeConstants.cpp +++ b/developer/src/kmcmplib/src/NamedCodeConstants.cpp @@ -24,7 +24,6 @@ #include "pch.h" #include #include "NamedCodeConstants.h" -#include "CheckFilenameConsistency.h" #include #include "kmcompx.h" @@ -117,10 +116,6 @@ char *kmc_strupr(char *s) { KMX_BOOL NamedCodeConstants::LoadFile(PFILE_KEYBOARD fk, const KMX_WCHAR *filename) { const int str_size = 256; - if (CheckFilenameConsistency(filename, FALSE) != 0) { - return FALSE; - } - auto szNameUtf8 = string_from_u16string(filename); int FileSize; diff --git a/developer/src/kmcmplib/src/meson.build b/developer/src/kmcmplib/src/meson.build index 2ca06929bc..c6ed2b84b0 100644 --- a/developer/src/kmcmplib/src/meson.build +++ b/developer/src/kmcmplib/src/meson.build @@ -37,29 +37,25 @@ icuuc_dep = icu.get_variable('icuuc_dep') lib = library('kmcmplib', 'CasedKeys.cpp', 'CharToKeyConversion.cpp', + 'CheckForDuplicates.cpp', + 'CheckNCapsConsistency.cpp', 'CompileKeyboardBuffer.cpp', 'Compiler.cpp', 'CompilerInterfaces.cpp', 'CompilerInterfacesWasm.cpp', + 'CompMsg.cpp', 'DeprecationChecks.cpp', 'Edition.cpp', + 'kmx_u16.cpp', 'NamedCodeConstants.cpp', + 'UnreachableRules.cpp', + 'uset-api.cpp', 'versioning.cpp', 'virtualcharkeys.cpp', 'xstring.cpp', - 'CharToKeyConversion.cpp', - 'CheckFilenameConsistency.cpp', - 'CheckForDuplicates.cpp', - 'CheckNCapsConsistency.cpp', - 'UnreachableRules.cpp', - 'kmx_u16.cpp', - 'CompMsg.cpp', - 'uset-api.cpp', - '../../../../common/windows/cpp/src/ConvertUTF.c', '../../../../common/windows/cpp/src/crc32.cpp', '../../../../common/windows/cpp/src/vkeys.cpp', - 'xstring.cpp', version_res, cpp_args: defns + warns + flags,