diff --git a/HISTORY.md b/HISTORY.md index 94efb781a8..22efd85bd6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,19 @@ # Keyman Version History +## 18.0.81 alpha 2024-08-03 + +* chore(developer): Revert "chore(developer): remove redundant references from tsconfig.json" (#12076) +* chore(common): use nvm in builds to select a node version automatically (#12069) +* refactor(developer): move functions and variables into CompilerErrors.cpp (#12030) +* refactor(developer): improve the callbacks for kmcmplib (#12031) +* refactor(developer): align kmcmplib error codes and names with kmc-kmn (#12044) +* refactor(developer): move error reporting to error site in kmcmplib (part 1) (#12045) +* refactor(developer): move error reporting inside `GetCompileTargetsFromTargetsStore` and `ProcessGroupFinish` (#12048) +* refactor(developer): move kmcmplib message construction to kmc-kmn (#12059) +* refactor(developer): rename compiler error reporting functions in kmcmplib (#12060) +* chore(developer): support filename field in kmcmplib compiler messages (#12061) +* refactor(developer): replace `VERIFY_KEYBOARD_VERSION()` calls with `VerifyKeyboardVersion()` (#12063) + ## 18.0.80 alpha 2024-07-31 * chore(developer): remove redundant references from tsconfig.json (#12037) diff --git a/VERSION.md b/VERSION.md index 956e25b0ba..716c613096 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.81 \ No newline at end of file +18.0.82 \ No newline at end of file diff --git a/common/windows/delphi/keyboards/kmxfileconsts.pas b/common/windows/delphi/keyboards/kmxfileconsts.pas index 2a32184ec0..e8f0e0d740 100644 --- a/common/windows/delphi/keyboards/kmxfileconsts.pas +++ b/common/windows/delphi/keyboards/kmxfileconsts.pas @@ -29,7 +29,6 @@ const SZMAX_GROUPNAME = 80; SZMAX_DEADKEYNAME = 80; SZMAX_VKDICTIONARYNAME = 80; // I3438 - SZMAX_ERRORTEXT = 512; SZMAX_LANGUAGENAME = 80; SZMAX_KEYBOARDNAME = 80; diff --git a/developer/src/common/include/kmn_compiler_errors.h b/developer/src/common/include/kmn_compiler_errors.h index 062cce291e..4955df5e73 100644 --- a/developer/src/common/include/kmn_compiler_errors.h +++ b/developer/src/common/include/kmn_compiler_errors.h @@ -23,21 +23,38 @@ #ifndef _kmn_compiler_errors_h #define _kmn_compiler_errors_h -// Compiler Error Masks +// Compiler Error Masks -- matches compiler-interfaces.ts -#define CERR_SEVERITY_MASK 0x0000F000 -#define CERR_MESSAGE_MASK 0x00000FFF -#define CERR_MASK 0x0000FFFF +namespace CompilerErrorSeverity { + // We use a namespace to stop the enum names leaking out into global namespace scope + enum { + Info = 0x000000, // Informational, not necessarily a problem + Hint = 0x100000, // Something the user might want to be aware of + Warn = 0x200000, // Warning: Not great, but we can keep going. + Error = 0x300000, // Severe error where we can't continue + Fatal = 0x400000, // OOM or should-not-happen internal problem + }; +}; -// Severity codes -// -// Note: these may not be combined, and are not a bitmask, for historical -// reasons they are separate bits -#define CERR_FATAL 0x00008000 -#define CERR_ERROR 0x00004000 -#define CERR_WARNING 0x00002000 -#define CERR_HINT 0x00001000 -#define CERR_INFO 0x00000000 +#define MESSAGE_SEVERITY_MASK 0x00F00000 // includes reserved bits, 16 possible severity levels +#define MESSAGE_ERROR_MASK 0x000FFFFF // error | namespace +#define MESSAGE_NAMESPACE_MASK 0x000FF000 // 256 possible namespaces +#define MESSAGE_BASEERROR_MASK 0x00000FFF // error code, 2,048 possible error codes per namespace +#define MESSAGE_RESERVED_MASK 0xFF000000 // do not use these error values at this time + +#define MESSAGE_NAMESPACE_KmnCompiler 0x2000 + +// Severity codes + namespace for shorthand use +#define SevFatal (MESSAGE_NAMESPACE_KmnCompiler | CompilerErrorSeverity::Fatal) +#define SevError (MESSAGE_NAMESPACE_KmnCompiler | CompilerErrorSeverity::Error) +#define SevWarn (MESSAGE_NAMESPACE_KmnCompiler | CompilerErrorSeverity::Warn) +#define SevHint (MESSAGE_NAMESPACE_KmnCompiler | CompilerErrorSeverity::Hint) +#define SevInfo (MESSAGE_NAMESPACE_KmnCompiler | CompilerErrorSeverity::Info) + +// These two values are not true error codes; they are used as +// return values in kmcmplib and are never passed to kmc-kmn +#define STATUS_Success 0x00000000 // NOTE: Not a message code +#define STATUS_EndOfFile 0x00000001 // NOTE: Not a message code // Message codes // @@ -46,215 +63,216 @@ // sure to update that file also. Note that this correlation is currently // maintained manually. All values must be below 0x1000 (exclusive of severity // code). -#define CERR_None 0x00000000 -#define CERR_EndOfFile 0x00000001 -#define CERR_BadCallParams 0x00008002 // TODO: rename to CFATAL_ -#define CERR_CannotAllocateMemory 0x00008004 // TODO: rename to CFATAL_ -#define CERR_InfileNotExist 0x00004005 // #10678: reduced from fatal to error in 17.0 -// #define CERR_CannotCreateOutfile 0x00004006 // #10678: reduced from fatal to error in 17.0, but unused -#define CERR_UnableToWriteFully 0x00008007 // TODO: rename to CFATAL_ -#define CERR_CannotReadInfile 0x00004008 // #10678: reduced from fatal to error in 17.0 -#define CERR_SomewhereIGotItWrong 0x00008009 // TODO: rename to CFATAL_ +namespace KmnCompilerMessages { + enum { + FATAL_BadCallParams = SevFatal | 0x002, + FATAL_CannotAllocateMemory = SevFatal | 0x004, + ERROR_InfileNotExist = SevError | 0x005, // #10678: reduced from fatal to error in 17.0 +// ERROR_CannotCreateOutfile = SevError | 0x006, // #10678: reduced from fatal to error in 17.0, but unused +// FATAL_UnableToWriteFully = SevFatal | 0x007, // unused + ERROR_CannotReadInfile = SevError | 0x008, // #10678: reduced from fatal to error in 17.0 + FATAL_SomewhereIGotItWrong = SevFatal | 0x009, -#define CERR_InvalidToken 0x0000400A -#define CERR_InvalidBegin 0x0000400B -#define CERR_InvalidName 0x0000400C -#define CERR_InvalidVersion 0x0000400D -#define CERR_InvalidLanguageLine 0x0000400E -#define CERR_LayoutButNoLanguage 0x0000400F -#define CERR_InvalidLayoutLine 0x00004010 -#define CERR_NoVersionLine 0x00004011 -#define CERR_InvalidGroupLine 0x00004012 -#define CERR_InvalidStoreLine 0x00004013 -#define CERR_InvalidCodeInKeyPartOfRule 0x00004014 -#define CERR_InvalidDeadkey 0x00004015 -#define CERR_InvalidValue 0x00004016 -#define CERR_ZeroLengthString 0x00004017 -#define CERR_TooManyIndexToKeyRefs 0x00004018 -#define CERR_UnterminatedString 0x00004019 -#define CERR_StringInVirtualKeySection 0x0000401A -#define CERR_AnyInVirtualKeySection 0x0000401B -#define CERR_InvalidAny 0x0000401C -#define CERR_StoreDoesNotExist 0x0000401D -#define CERR_BeepInVirtualKeySection 0x0000401E -#define CERR_IndexInVirtualKeySection 0x0000401F -#define CERR_InvalidIndex 0x00004020 -#define CERR_OutsInVirtualKeySection 0x00004021 -#define CERR_InvalidOuts 0x00004022 -#define CERR_ContextInVirtualKeySection 0x00004024 -#define CERR_InvalidUse 0x00004025 -#define CERR_GroupDoesNotExist 0x00004026 -#define CERR_VirtualKeyNotAllowedHere 0x00004027 -#define CERR_InvalidSwitch 0x00004028 -#define CERR_NoTokensFound 0x00004029 -#define CERR_InvalidLineContinuation 0x0000402A -#define CERR_LineTooLong 0x0000402B -#define CERR_InvalidCopyright 0x0000402C -#define CERR_CodeInvalidInThisSection 0x0000402D -#define CERR_InvalidMessage 0x0000402E -#define CERR_InvalidLanguageName 0x0000402F -#define CERR_InvalidBitmapLine 0x00004030 -#define CERR_CannotReadBitmapFile 0x00004031 -#define CERR_IndexDoesNotPointToAny 0x00004032 -#define CERR_ReservedCharacter 0x00004033 -#define CERR_InvalidCharacter 0x00004034 -#define CERR_InvalidCall 0x00004035 -#define CERR_CallInVirtualKeySection 0x00004036 -#define CERR_CodeInvalidInKeyStore 0x00004037 -#define CERR_CannotLoadIncludeFile 0x00004038 + ERROR_InvalidToken = SevError | 0x00A, + ERROR_InvalidBegin = SevError | 0x00B, + ERROR_InvalidName = SevError | 0x00C, + ERROR_InvalidVersion = SevError | 0x00D, + ERROR_InvalidLanguageLine = SevError | 0x00E, + ERROR_LayoutButNoLanguage = SevError | 0x00F, + ERROR_InvalidLayoutLine = SevError | 0x010, + ERROR_NoVersionLine = SevError | 0x011, + ERROR_InvalidGroupLine = SevError | 0x012, + ERROR_InvalidStoreLine = SevError | 0x013, + ERROR_InvalidCodeInKeyPartOfRule = SevError | 0x014, + ERROR_InvalidDeadkey = SevError | 0x015, + ERROR_InvalidValue = SevError | 0x016, + ERROR_ZeroLengthString = SevError | 0x017, + ERROR_TooManyIndexToKeyRefs = SevError | 0x018, + ERROR_UnterminatedString = SevError | 0x019, + ERROR_StringInVirtualKeySection = SevError | 0x01A, + ERROR_AnyInVirtualKeySection = SevError | 0x01B, + ERROR_InvalidAny = SevError | 0x01C, + ERROR_StoreDoesNotExist = SevError | 0x01D, + ERROR_BeepInVirtualKeySection = SevError | 0x01E, + ERROR_IndexInVirtualKeySection = SevError | 0x01F, + ERROR_InvalidIndex = SevError | 0x020, + ERROR_OutsInVirtualKeySection = SevError | 0x021, + ERROR_InvalidOuts = SevError | 0x022, + ERROR_ContextInVirtualKeySection = SevError | 0x024, + ERROR_InvalidUse = SevError | 0x025, + ERROR_GroupDoesNotExist = SevError | 0x026, + ERROR_VirtualKeyNotAllowedHere = SevError | 0x027, + ERROR_InvalidSwitch = SevError | 0x028, + ERROR_NoTokensFound = SevError | 0x029, + ERROR_InvalidLineContinuation = SevError | 0x02A, + ERROR_LineTooLong = SevError | 0x02B, + ERROR_InvalidCopyright = SevError | 0x02C, + ERROR_CodeInvalidInThisSection = SevError | 0x02D, + ERROR_InvalidMessage = SevError | 0x02E, + ERROR_InvalidLanguageName = SevError | 0x02F, + ERROR_InvalidBitmapLine = SevError | 0x030, + ERROR_CannotReadBitmapFile = SevError | 0x031, + ERROR_IndexDoesNotPointToAny = SevError | 0x032, + ERROR_ReservedCharacter = SevError | 0x033, + ERROR_InvalidCharacter = SevError | 0x034, + ERROR_InvalidCall = SevError | 0x035, + ERROR_CallInVirtualKeySection = SevError | 0x036, + ERROR_CodeInvalidInKeyStore = SevError | 0x037, + ERROR_CannotLoadIncludeFile = SevError | 0x038, -#define CERR_60FeatureOnly_EthnologueCode 0x00004039 -#define CERR_60FeatureOnly_MnemonicLayout 0x0000403A -#define CERR_60FeatureOnly_OldCharPosMatching 0x0000403B -#define CERR_60FeatureOnly_NamedCodes 0x0000403C -#define CERR_60FeatureOnly_Contextn 0x0000403D -#define CERR_501FeatureOnly_Call 0x0000403E + ERROR_60FeatureOnly_EthnologueCode = SevError | 0x039, + ERROR_60FeatureOnly_MnemonicLayout = SevError | 0x03A, + ERROR_60FeatureOnly_OldCharPosMatching = SevError | 0x03B, + ERROR_60FeatureOnly_NamedCodes = SevError | 0x03C, + ERROR_60FeatureOnly_Contextn = SevError | 0x03D, + ERROR_501FeatureOnly_Call = SevError | 0x03E, -#define CERR_InvalidNamedCode 0x0000403F -#define CERR_InvalidSystemStore 0x00004040 + ERROR_InvalidNamedCode = SevError | 0x03F, + ERROR_InvalidSystemStore = SevError | 0x040, -#define CERR_60FeatureOnly_VirtualCharKey 0x00004044 + ERROR_60FeatureOnly_VirtualCharKey = SevError | 0x044, -#define CERR_VersionAlreadyIncluded 0x00004045 + ERROR_VersionAlreadyIncluded = SevError | 0x045, -#define CERR_70FeatureOnly 0x00004046 + ERROR_70FeatureOnly = SevError | 0x046, -#define CERR_80FeatureOnly 0x00004047 -#define CERR_InvalidInVirtualKeySection 0x00004048 -#define CERR_InvalidIf 0x00004049 -#define CERR_InvalidReset 0x0000404A -#define CERR_InvalidSet 0x0000404B -#define CERR_InvalidSave 0x0000404C + ERROR_80FeatureOnly = SevError | 0x047, + ERROR_InvalidInVirtualKeySection = SevError | 0x048, + ERROR_InvalidIf = SevError | 0x049, + ERROR_InvalidReset = SevError | 0x04A, + ERROR_InvalidSet = SevError | 0x04B, + ERROR_InvalidSave = SevError | 0x04C, -#define CERR_InvalidEthnologueCode 0x0000404D + ERROR_InvalidEthnologueCode = SevError | 0x04D, -#define CERR_CannotCreateTempfile 0x0000804E // TODO: rename to CFATAL_ + FATAL_CannotCreateTempfile = SevFatal | 0x04E, -#define CERR_90FeatureOnly_IfSystemStores 0x0000404F -#define CERR_IfSystemStore_NotFound 0x00004050 -#define CERR_90FeatureOnly_SetSystemStores 0x00004051 -#define CERR_SetSystemStore_NotFound 0x00004052 -#define CERR_90FeatureOnlyVirtualKeyDictionary 0x00004053 + ERROR_90FeatureOnly_IfSystemStores = SevError | 0x04F, + ERROR_IfSystemStore_NotFound = SevError | 0x050, + ERROR_90FeatureOnly_SetSystemStores = SevError | 0x051, + ERROR_SetSystemStore_NotFound = SevError | 0x052, + ERROR_90FeatureOnlyVirtualKeyDictionary = SevError | 0x053, -#define CERR_NotSupportedInKeymanWebContext 0x00004054 -#define CERR_NotSupportedInKeymanWebOutput 0x00004055 -#define CERR_NotSupportedInKeymanWebStore 0x00004056 -#define CERR_VirtualCharacterKeysNotSupportedInKeymanWeb 0x00004057 -#define CERR_VirtualKeysNotValidForMnemonicLayouts 0x00004058 -#define CERR_InvalidTouchLayoutFile 0x00004059 -#define CERR_TouchLayoutInvalidIdentifier 0x0000405A -#define CERR_InvalidKeyCode 0x0000405B -#define CERR_90FeatureOnlyLayoutFile 0x0000405C -#define CERR_90FeatureOnlyKeyboardVersion 0x0000405D -#define CERR_KeyboardVersionFormatInvalid 0x0000405E -#define CERR_ContextExHasInvalidOffset 0x0000405F -#define CERR_90FeatureOnlyEmbedCSS 0x00004060 -#define CERR_90FeatureOnlyTargets 0x00004061 -#define CERR_ContextAndIndexInvalidInMatchNomatch 0x00004062 -#define CERR_140FeatureOnlyContextAndNotAnyWeb 0x00004063 + ERROR_NotSupportedInKeymanWebContext = SevError | 0x054, + ERROR_NotSupportedInKeymanWebOutput = SevError | 0x055, + ERROR_NotSupportedInKeymanWebStore = SevError | 0x056, + ERROR_VirtualCharacterKeysNotSupportedInKeymanWeb = SevError | 0x057, + ERROR_VirtualKeysNotValidForMnemonicLayouts = SevError | 0x058, + ERROR_InvalidTouchLayoutFile = SevError | 0x059, + ERROR_TouchLayoutInvalidIdentifier = SevError | 0x05A, + ERROR_InvalidKeyCode = SevError | 0x05B, + ERROR_90FeatureOnlyLayoutFile = SevError | 0x05C, + ERROR_90FeatureOnlyKeyboardVersion = SevError | 0x05D, + ERROR_KeyboardVersionFormatInvalid = SevError | 0x05E, + ERROR_ContextExHasInvalidOffset = SevError | 0x05F, + ERROR_90FeatureOnlyEmbedCSS = SevError | 0x060, + ERROR_90FeatureOnlyTargets = SevError | 0x061, + ERROR_ContextAndIndexInvalidInMatchNomatch = SevError | 0x062, + ERROR_140FeatureOnlyContextAndNotAnyWeb = SevError | 0x063, -#define CERR_ExpansionMustFollowCharacterOrVKey 0x00004064 -#define CERR_VKeyExpansionMustBeFollowedByVKey 0x00004065 -#define CERR_CharacterExpansionMustBeFollowedByCharacter 0x00004066 -#define CERR_VKeyExpansionMustUseConsistentShift 0x00004067 -#define CERR_ExpansionMustBePositive 0x00004068 + ERROR_ExpansionMustFollowCharacterOrVKey = SevError | 0x064, + ERROR_VKeyExpansionMustBeFollowedByVKey = SevError | 0x065, + ERROR_CharacterExpansionMustBeFollowedByCharacter = SevError | 0x066, + ERROR_VKeyExpansionMustUseConsistentShift = SevError | 0x067, + ERROR_ExpansionMustBePositive = SevError | 0x068, -#define CERR_CasedKeysMustContainOnlyVirtualKeys 0x00004069 -#define CERR_CasedKeysMustNotIncludeShiftStates 0x0000406A -#define CERR_CasedKeysNotSupportedWithMnemonicLayout 0x0000406B + ERROR_CasedKeysMustContainOnlyVirtualKeys = SevError | 0x069, + ERROR_CasedKeysMustNotIncludeShiftStates = SevError | 0x06A, + ERROR_CasedKeysNotSupportedWithMnemonicLayout = SevError | 0x06B, -#define CERR_CannotUseReadWriteGroupFromReadonlyGroup 0x0000406C -#define CERR_StatementNotPermittedInReadonlyGroup 0x0000406D -#define CERR_OutputInReadonlyGroup 0x0000406E -#define CERR_NewContextGroupMustBeReadonly 0x0000406F -#define CERR_PostKeystrokeGroupMustBeReadonly 0x00004070 + ERROR_CannotUseReadWriteGroupFromReadonlyGroup = SevError | 0x06C, + ERROR_StatementNotPermittedInReadonlyGroup = SevError | 0x06D, + ERROR_OutputInReadonlyGroup = SevError | 0x06E, + ERROR_NewContextGroupMustBeReadonly = SevError | 0x06F, + ERROR_PostKeystrokeGroupMustBeReadonly = SevError | 0x070, -#define CERR_DuplicateGroup 0x00004071 -#define CERR_DuplicateStore 0x00004072 -#define CERR_RepeatedBegin 0x00004073 -#define CERR_VirtualKeyInContext 0x00004074 + ERROR_DuplicateGroup = SevError | 0x071, + ERROR_DuplicateStore = SevError | 0x072, + ERROR_RepeatedBegin = SevError | 0x073, + ERROR_VirtualKeyInContext = SevError | 0x074, -#define CERR_OutsTooLong 0x00004075 -#define CERR_ExtendedStringTooLong 0x00004076 -#define CERR_VirtualKeyExpansionTooLong 0x00004077 -#define CERR_CharacterRangeTooLong 0x00004078 -#define CERR_NonBMPCharactersNotSupportedInKeySection 0x00004079 + ERROR_OutsTooLong = SevError | 0x075, + ERROR_ExtendedStringTooLong = SevError | 0x076, + ERROR_VirtualKeyExpansionTooLong = SevError | 0x077, + ERROR_CharacterRangeTooLong = SevError | 0x078, + ERROR_NonBMPCharactersNotSupportedInKeySection = SevError | 0x079, -#define CERR_InvalidTarget 0x0000407A -#define CERR_NoTargetsSpecified 0x0000407B + ERROR_InvalidTarget = SevError | 0x07A, + ERROR_NoTargetsSpecified = SevError | 0x07B, -#define CWARN_TooManyWarnings 0x00002080 -#define CWARN_OldVersion 0x00002081 -#define CWARN_BitmapNotUsed 0x00002082 -#define CWARN_CustomLanguagesNotSupported 0x00002083 -#define CWARN_KeyBadLength 0x00002084 -#define CWARN_IndexStoreShort 0x00002085 -#define CWARN_UnicodeInANSIGroup 0x00002086 -#define CWARN_ANSIInUnicodeGroup 0x00002087 -#define CWARN_UnicodeSurrogateUsed 0x00002088 -#define CWARN_ReservedCharacter 0x00002089 -// Note: CWARN_Info has an "info" severity; this changed in 17.0. Earlier versions -// had a special case for CWARN_Info in message output. -#define CWARN_Info 0x0000008A -#define CINFO_Info CWARN_Info -#define CWARN_VirtualKeyWithMnemonicLayout 0x0000208B -#define CWARN_VirtualCharKeyWithPositionalLayout 0x0000208C -#define CWARN_StoreAlreadyUsedAsOptionOrCall 0x0000208D -#define CWARN_StoreAlreadyUsedAsStoreOrCall 0x0000208E -#define CWARN_StoreAlreadyUsedAsStoreOrOption 0x0000208F + WARN_TooManyWarnings = SevWarn | 0x080, + WARN_OldVersion = SevWarn | 0x081, + WARN_BitmapNotUsed = SevWarn | 0x082, + WARN_CustomLanguagesNotSupported = SevWarn | 0x083, + WARN_KeyBadLength = SevWarn | 0x084, + WARN_IndexStoreShort = SevWarn | 0x085, + WARN_UnicodeInANSIGroup = SevWarn | 0x086, + WARN_ANSIInUnicodeGroup = SevWarn | 0x087, + WARN_UnicodeSurrogateUsed = SevWarn | 0x088, + WARN_ReservedCharacter = SevWarn | 0x089, -#define CWARN_PunctuationInEthnologueCode 0x00002090 + INFO_MinimumCoreEngineVersion = SevInfo | 0x08A, // renamed from INFO_Info in 18.0-alpha -#define CWARN_TouchLayoutMissingLayer 0x00002091 -#define CWARN_TouchLayoutCustomKeyNotDefined 0x00002092 -#define CWARN_TouchLayoutMissingRequiredKeys 0x00002093 -#define CWARN_HelpFileMissing 0x00002094 -#define CWARN_EmbedJsFileMissing 0x00002095 -#define CWARN_TouchLayoutFileMissing 0x00002096 -#define CWARN_VisualKeyboardFileMissing 0x00002097 -#define CWARN_ExtendedShiftFlagsNotSupportedInKeymanWeb 0x00002098 // I4118 -#define CWARN_TouchLayoutUnidentifiedKey 0x00002099 -#define CHINT_UnreachableKeyCode 0x0000109A + WARN_VirtualKeyWithMnemonicLayout = SevWarn | 0x08B, + WARN_VirtualCharKeyWithPositionalLayout = SevWarn | 0x08C, + WARN_StoreAlreadyUsedAsOptionOrCall = SevWarn | 0x08D, + WARN_StoreAlreadyUsedAsStoreOrCall = SevWarn | 0x08E, + WARN_StoreAlreadyUsedAsStoreOrOption = SevWarn | 0x08F, -#define CWARN_CouldNotCopyJsonFile 0x0000209B -#define CWARN_PlatformNotInTargets 0x0000209C + WARN_PunctuationInEthnologueCode = SevWarn | 0x090, -#define CWARN_HeaderStatementIsDeprecated 0x0000209D -#define CWARN_UseNotLastStatementInRule 0x0000209E + WARN_TouchLayoutMissingLayer = SevWarn | 0x091, + WARN_TouchLayoutCustomKeyNotDefined = SevWarn | 0x092, + WARN_TouchLayoutMissingRequiredKeys = SevWarn | 0x093, + WARN_HelpFileMissing = SevWarn | 0x094, + WARN_EmbedJsFileMissing = SevWarn | 0x095, + // WARN_TouchLayoutFileMissing = SevWarn | 0x096, + // WARN_VisualKeyboardFileMissing = SevWarn | 0x097, + WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb = SevWarn | 0x098, // I4118 + WARN_TouchLayoutUnidentifiedKey = SevWarn | 0x099, + HINT_UnreachableKeyCode = SevHint | 0x09A, -#define CWARN_TouchLayoutFontShouldBeSameForAllPlatforms 0x0000209F -#define CWARN_InvalidJSONMetadataFile 0x000020A0 -#define CWARN_JSONMetadataOSKFontShouldMatchTouchFont 0x000020A1 -#define CWARN_KVKFileIsInSourceFormat 0x000020A2 + // WARN_CouldNotCopyJsonFile = SevWarn | 0x09B, + WARN_PlatformNotInTargets = SevWarn | 0x09C, -#define CWARN_DontMixChiralAndNonChiralModifiers 0x000020A3 -#define CWARN_MixingLeftAndRightModifiers 0x000020A4 + WARN_HeaderStatementIsDeprecated = SevWarn | 0x09D, + WARN_UseNotLastStatementInRule = SevWarn | 0x09E, -#define CWARN_LanguageHeadersDeprecatedInKeyman10 0x000020A5 + WARN_TouchLayoutFontShouldBeSameForAllPlatforms = SevWarn | 0x09F, + // WARN_InvalidJSONMetadataFile = SevWarn | 0x0A0, + // WARN_JSONMetadataOSKFontShouldMatchTouchFont = SevWarn | 0x0A1, + WARN_KVKFileIsInSourceFormat = SevWarn | 0x0A2, -#define CHINT_NonUnicodeFile 0x000010A6 + WARN_DontMixChiralAndNonChiralModifiers = SevWarn | 0x0A3, + WARN_MixingLeftAndRightModifiers = SevWarn | 0x0A4, -#define CWARN_TooManyErrorsOrWarnings 0x000020A7 + WARN_LanguageHeadersDeprecatedInKeyman10 = SevWarn | 0x0A5, -#define CWARN_HotkeyHasInvalidModifier 0x000020A8 + HINT_NonUnicodeFile = SevHint | 0x0A6, -#define CWARN_TouchLayoutSpecialLabelOnNormalKey 0x000020A9 + // WARN_TooManyErrorsOrWarnings = SevWarn | 0x0A7, -#define CWARN_OptionStoreNameInvalid 0x000020AA + WARN_HotkeyHasInvalidModifier = SevWarn | 0x0A8, -#define CWARN_NulNotFirstStatementInContext 0x000020AB -#define CWARN_IfShouldBeAtStartOfContext 0x000020AC + WARN_TouchLayoutSpecialLabelOnNormalKey = SevWarn | 0x0A9, -#define CWARN_KeyShouldIncludeNCaps 0x000020AD + WARN_OptionStoreNameInvalid = SevWarn | 0x0AA, -#define CHINT_UnreachableRule 0x000010AE + WARN_NulNotFirstStatementInContext = SevWarn | 0x0AB, + WARN_IfShouldBeAtStartOfContext = SevWarn | 0x0AC, -#define CWARN_VirtualKeyInOutput 0x000020AF + WARN_KeyShouldIncludeNCaps = SevWarn | 0x0AD, -#define CHINT_IndexStoreLong 0x000010B0 + HINT_UnreachableRule = SevHint | 0x0AE, -#define CERR_BufferOverflow 0x000080C0 // TODO: Rename to CFATAL_... -#define CERR_Break 0x000080C1 // TODO: Rename to CFATAL_... + WARN_VirtualKeyInOutput = SevWarn | 0x0AF, + + HINT_IndexStoreLong = SevHint | 0x0B0, + + FATAL_BufferOverflow = SevFatal | 0x0C0 +// FATAL_Break = SevFatal | 0x0C1, unused + }; +} #endif // _kmn_compiler_errors_h diff --git a/developer/src/common/web/test-helpers/tsconfig.json b/developer/src/common/web/test-helpers/tsconfig.json index de7b86b4e0..dd0e738096 100644 --- a/developer/src/common/web/test-helpers/tsconfig.json +++ b/developer/src/common/web/test-helpers/tsconfig.json @@ -9,4 +9,7 @@ "include": [ "./*.ts", ], + "references": [ + { "path": "../../../../../common/web/types/" }, + ] } \ No newline at end of file diff --git a/developer/src/common/web/utils/test/tsconfig.json b/developer/src/common/web/utils/test/tsconfig.json index 5fe319264e..fdf5fd474f 100644 --- a/developer/src/common/web/utils/test/tsconfig.json +++ b/developer/src/common/web/utils/test/tsconfig.json @@ -15,6 +15,7 @@ "helpers/*.ts", ], "references": [ - { "path": "../" }, - ], + { "path": "../" }, + { "path": "../../test-helpers/" }, + ] } \ No newline at end of file diff --git a/developer/src/kmc-analyze/tsconfig.json b/developer/src/kmc-analyze/tsconfig.json index 2039577391..3951ed3a40 100644 --- a/developer/src/kmc-analyze/tsconfig.json +++ b/developer/src/kmc-analyze/tsconfig.json @@ -9,4 +9,9 @@ "include": [ "src/**/*.ts" ], + "references": [ + { "path": "../../../common/web/types" }, + { "path": "../kmc-kmn" }, + { "path": "../common/web/utils/" }, + ] } diff --git a/developer/src/kmc-keyboard-info/test/tsconfig.json b/developer/src/kmc-keyboard-info/test/tsconfig.json index 5f74a1dc19..e16b935aa4 100644 --- a/developer/src/kmc-keyboard-info/test/tsconfig.json +++ b/developer/src/kmc-keyboard-info/test/tsconfig.json @@ -15,5 +15,7 @@ ], "references": [ { "path": "../" }, + { "path": "../../common/web/test-helpers/" }, + { "path": "../../kmc-package/" }, ] } \ No newline at end of file diff --git a/developer/src/kmc-keyboard-info/tsconfig.json b/developer/src/kmc-keyboard-info/tsconfig.json index 981541e90c..d09b25c560 100644 --- a/developer/src/kmc-keyboard-info/tsconfig.json +++ b/developer/src/kmc-keyboard-info/tsconfig.json @@ -16,4 +16,9 @@ "src/ttfmeta/lib/*.js", "src/imports/langtags.js", ], + "references": [ + { "path": "../../../common/web/types" }, + { "path": "../kmc-package/" }, + { "path": "../common/web/utils/" }, + ] } diff --git a/developer/src/kmc-kmn/src/compiler/compiler.ts b/developer/src/kmc-kmn/src/compiler/compiler.ts index 0b85256337..f8938be60e 100644 --- a/developer/src/kmc-kmn/src/compiler/compiler.ts +++ b/developer/src/kmc-kmn/src/compiler/compiler.ts @@ -10,7 +10,7 @@ import { UnicodeSetParser, UnicodeSet, VisualKeyboard, KvkFileReader, KeymanComp import { CompilerCallbacks, CompilerEvent, CompilerOptions, KeymanFileTypes, KvkFileWriter, KvksFileReader } from '@keymanapp/common-types'; import * as Osk from './osk.js'; import loadWasmHost from '../import/kmcmplib/wasm-host.js'; -import { KmnCompilerMessages, mapErrorFromKmcmplib } from './kmn-compiler-messages.js'; +import { KmnCompilerMessages } from './kmn-compiler-messages.js'; import { WriteCompiledKeyboard } from '../kmw-compiler/kmw-compiler.js'; // @@ -57,6 +57,15 @@ export interface KmnCompilerResultExtra { groups: CompilerResultExtraGroup[]; }; +/** @internal */ +export interface KmnCompilerResultMessage { + errorCode: number; + lineNumber: number; + columnNumber: number; + filename: string; + parameters: string[]; +} + /** * @public * Internal in-memory build artifacts from a successful compilation @@ -114,16 +123,6 @@ const baseOptions: KmnCompilerOptions = { warnDeprecatedCode: true, }; -/** - * Allows multiple instances of the Compiler class, by ensuring that the - * 'unique' kmnCompilerCallback global will be correlated with a specific - * instance of the Compiler class - */ -let callbackProcIdentifier = 0; - -const - callbackPrefix = 'kmnCompilerCallbacks_'; - interface MallocAndFree { malloc(sz: number) : number; free(p: number) : null; @@ -139,16 +138,10 @@ let * external IO. */ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { - private readonly callbackID: string; // a unique numeric id added to globals with prefixed names private callbacks: CompilerCallbacks; private wasmExports: MallocAndFree; private options: KmnCompilerOptions; - constructor() { - this.callbackID = callbackPrefix + callbackProcIdentifier.toString(); - callbackProcIdentifier++; - } - /** * Initialize the compiler, including loading the WASM host for kmcmplib. * Copies options. @@ -220,46 +213,6 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { return true; } - private compilerMessageCallback = (line: number, code: number, msg: string): number => { - this.callbacks.reportMessage(mapErrorFromKmcmplib(line, code, msg)); - return 1; - } - - private cachedFile: {filename: string; data: Uint8Array} = { - filename: null, - data: null - }; - - private loadFileCallback = (filename: string, baseFilename: string, buffer: number, bufferSize: number): number => { - let resolvedFilename = this.callbacks.resolveFilename(baseFilename, filename); - let data: Uint8Array; - if(this.cachedFile.filename == resolvedFilename) { - data = this.cachedFile.data; - } - else { - data = this.callbacks.loadFile(resolvedFilename); - if(!data) { - return -1; - } - this.cachedFile.filename = resolvedFilename; - this.cachedFile.data = data; - } - - if(buffer == 0) { - /* We need to return buffer size required */ - return data.byteLength; - } - - if(bufferSize != data.byteLength) { - /* c8 ignore next 2 */ - throw new Error(`loadFileCallback: second call, expected file size ${bufferSize} == ${data.byteLength}`); - } - - Module.HEAP8.set(data, buffer); - - return 1; - } - private copyWasmResult(wasm_result: any): KmnCompilerResult { let result: KmnCompilerResult = { // We cannot Object.assign or {...} on a wasm-defined object, so... @@ -299,6 +252,31 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { return new Uint8Array(new Uint8Array(Module.HEAP8.buffer, offset, size)); } + private toTitleCase = (s: string) => s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); + + private generateKmcmpLibMessage(filename: string, line: number, code: number, parameters: string[]) { + const keys = Object.keys(KmnCompilerMessages); + const m = KmnCompilerMessages as Record; + const key = keys.find(key => m[key] === code); + if(!key) { + return `Unknown message ${code.toString(16)} -- message identifier not found`; + } + + const o = /^(INFO|HINT|WARN|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(key); + if(!o) { + return `Unknown message ${code.toString(16)} -- message identifier is not a valid format`; + } + + const generator = this.toTitleCase(o[1])+'_'+o[2]; + if(!generator || typeof m[generator] != 'function') { + return `Unknown message ${code.toString(16)} -- generator function not found`; + } + const result = m[generator]({p:parameters}); + result.filename = filename; + result.line = line; + return result; + } + /** * Compiles a .kmn file to .kmx, .kvk, and/or .js files. Returns an object * containing binary artifacts on success. The files are passed in by name, @@ -322,12 +300,17 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { outfile = outfile ?? infile.replace(/\.kmn$/i, '.kmx'); - (globalThis as any)[this.callbackID] = { - message: this.compilerMessageCallback, - loadFile: this.loadFileCallback - }; + const compiler = this; + const wasm_callbacks = Module.WasmCallbackInterface.implement({ + message: function(message: KmnCompilerResultMessage) { + compiler.callbacks.reportMessage(compiler.generateKmcmpLibMessage(message.filename, message.lineNumber, message.errorCode, message.parameters)); + }, + loadFile: function(filename: string, baseFilename: string): number[] { + const data: Uint8Array = compiler.callbacks.loadFile(compiler.callbacks.resolveFilename(baseFilename, filename)); + return data ? Array.from(data) : null; + } + }); - let wasm_interface = new Module.CompilerInterface(); let wasm_options = new Module.CompilerOptions(); let wasm_result = null; try { @@ -336,8 +319,8 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { wasm_options.warnDeprecatedCode = options.warnDeprecatedCode; wasm_options.shouldAddCompilerVersion = options.shouldAddCompilerVersion; wasm_options.target = 0; // CKF_KEYMAN; TODO use COMPILETARGETS_KMX - wasm_interface.callbacksKey = this.callbackID; // key of object on globalThis - wasm_result = Module.kmcmp_compile(infile, wasm_options, wasm_interface); + + wasm_result = Module.kmcmp_compile(infile, wasm_options, wasm_callbacks); if(!wasm_result.result) { return null; } @@ -382,7 +365,7 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { // should have no impact on the final .js if options.debug is false wasm_options.saveDebug = true; - wasm_result = Module.kmcmp_compile(infile, wasm_options, wasm_interface); + wasm_result = Module.kmcmp_compile(infile, wasm_options, wasm_callbacks); if(!wasm_result.result) { return null; } @@ -405,9 +388,8 @@ export class KmnCompiler implements KeymanCompiler, UnicodeSetParser { if(wasm_result) { wasm_result.delete(); } - wasm_interface.delete(); + wasm_callbacks.delete(); wasm_options.delete(); - delete (globalThis as any)[this.callbackID]; } } diff --git a/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts b/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts index 926e1e9fb2..d40da3f492 100644 --- a/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts +++ b/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts @@ -18,30 +18,6 @@ const mw = (code: number, message: string, o?: {filename?: string, line?: number line: o?.line, }); -/** - * LogLevel comes from kmn_compiler_errors.h, for legacy compiler error messages - */ -const enum LogLevel { - LEVEL_MASK = 0xF000, - CODE_MASK = 0x0FFF, - CERR_FATAL = 0x8000, - CERR_ERROR = 0x4000, - CERR_WARNING = 0x2000, - CERR_HINT = 0x1000, - CERR_INFO = 0 -}; - -/** - * Translate the legacy compiler error messages to Severity codes - */ -const LogLevelToSeverity: Record = { - [LogLevel.CERR_FATAL]: SevFatal, - [LogLevel.CERR_ERROR]: SevError, - [LogLevel.CERR_WARNING]: SevWarn, - [LogLevel.CERR_HINT]: SevHint, - [LogLevel.CERR_INFO]: SevInfo -} - export const enum KmnCompilerMessageRanges { RANGE_KMN_COMPILER_MIN = 0x001, // from kmn_compiler_errors.h RANGE_KMN_COMPILER_MAX = 0x7FF, // from kmn_compiler_errors.h @@ -51,6 +27,8 @@ export const enum KmnCompilerMessageRanges { RANGE_CompilerMessage_Max = 0xFFF, // Highest available error code for kmc-kmn } +type KmcmpLibMessageParameters = {p:string[]}; + /** * @internal * @@ -211,10 +189,8 @@ export class KmnCompilerMessages { to the file.` ); - // static INFO_None = SevInfo | 0x000; - - static INFO_EndOfFile = SevInfo | 0x001; - static Info_EndOfFile = () => m(this.INFO_EndOfFile, `(no error - reserved code)`); + // static STATUS_None = 0x000; // This is not a real error + // static STATUS_EndOfFile = 0x001; // This is not a real error static FATAL_BadCallParams = SevFatal | 0x002; static Fatal_BadCallParams = () => m(this.FATAL_BadCallParams, `CompileKeyboardFile was called with bad parameters`); @@ -228,8 +204,8 @@ export class KmnCompilerMessages { // static ERROR_CannotCreateOutfile = SevError | 0x006; // #10678: reduced from fatal to error in 17.0, but unused // static Error_CannotCreateOutfile = () => m(this.ERROR_CannotCreateOutfile, `Cannot open output file for writing`); unused - static FATAL_UnableToWriteFully = SevFatal | 0x007; - static Fatal_UnableToWriteFully = () => m(this.FATAL_UnableToWriteFully, `Unable to write the file completely`); + // static FATAL_UnableToWriteFully = SevFatal | 0x007; + // static Fatal_UnableToWriteFully = () => m(this.FATAL_UnableToWriteFully, `Unable to write the file completely`); static ERROR_CannotReadInfile = SevError | 0x008; // #10678: reduced from fatal to error in 17.0 static Error_CannotReadInfile = () => m(this.ERROR_CannotReadInfile, `Cannot read the input file`); @@ -548,10 +524,16 @@ export class KmnCompilerMessages { static Error_PostKeystrokeGroupMustBeReadonly = () => m(this.ERROR_PostKeystrokeGroupMustBeReadonly, `Group used in begin postKeystroke must be readonly`); static ERROR_DuplicateGroup = SevError | 0x071; - static Error_DuplicateGroup = () => m(this.ERROR_DuplicateGroup, `A group with this name has already been defined.`); + static Error_DuplicateGroup = (o:KmcmpLibMessageParameters) => m( + this.ERROR_DuplicateGroup, + `A group with the name '${o.p?.[0]}' has already been defined on line ${o.p?.[1]}.` + ); static ERROR_DuplicateStore = SevError | 0x072; - static Error_DuplicateStore = () => m(this.ERROR_DuplicateStore, `A store with this name has already been defined.`); + static Error_DuplicateStore = (o:KmcmpLibMessageParameters) => m( + this.ERROR_DuplicateStore, + `A store with the name '${o.p?.[0]}' has already been defined on line ${o.p?.[1]}.` + ); static ERROR_RepeatedBegin = SevError | 0x073; static Error_RepeatedBegin = () => m(this.ERROR_RepeatedBegin, `Begin has already been set`); @@ -575,7 +557,10 @@ export class KmnCompilerMessages { static Error_NonBMPCharactersNotSupportedInKeySection = () => m(this.ERROR_NonBMPCharactersNotSupportedInKeySection, `Characters with codepoints over U+FFFF are not supported in the key part of the rule`); static ERROR_InvalidTarget = SevError | 0x07A; - static Error_InvalidTarget = () => m(this.ERROR_InvalidTarget, `Unrecognized compile target`); + static Error_InvalidTarget = (o:KmcmpLibMessageParameters) => m( + this.ERROR_InvalidTarget, + `Unrecognized compile target '${o.p?.[0]}'` + ); static ERROR_NoTargetsSpecified = SevError | 0x07B; static Error_NoTargetsSpecified = () => m(this.ERROR_NoTargetsSpecified, `At least one compile target must be specified`); @@ -610,10 +595,11 @@ export class KmnCompilerMessages { static WARN_ReservedCharacter = SevWarn | 0x089; static Warn_ReservedCharacter = () => m(this.WARN_ReservedCharacter, `A Unicode character was found that should not be used`); - // Note: INFO_Info is called CWARN_Info in kmn_compiler_errors.h, but should have an "info" severity - static INFO_Info = SevInfo | 0x08A; - static Info_Info = () => m(this.INFO_Info, `Information`); - + static INFO_MinimumCoreEngineVersion = SevInfo | 0x08A; + static Info_MinimumCoreEngineVersion = (o:KmcmpLibMessageParameters) => m( + this.INFO_MinimumCoreEngineVersion, + `The compiler has assigned a minimum engine version of ${o.p?.[0]}.${o.p?.[1]} based on features used in this keyboard` + ); static WARN_VirtualKeyWithMnemonicLayout = SevWarn | 0x08B; static Warn_VirtualKeyWithMnemonicLayout = () => m(this.WARN_VirtualKeyWithMnemonicLayout, `Virtual key used instead of virtual character key with a mnemonic layout`); @@ -730,7 +716,10 @@ export class KmnCompilerMessages { static Warn_KeyShouldIncludeNCaps = () => m(this.WARN_KeyShouldIncludeNCaps, `Other rules which reference this key include CAPS or NCAPS modifiers, so this rule must include NCAPS modifier to avoid inconsistent matches`); static HINT_UnreachableRule = SevHint | 0x0AE; - static Hint_UnreachableRule = () => m(this.HINT_UnreachableRule, `This rule will never be matched as another rule takes precedence`); + static Hint_UnreachableRule = (o:KmcmpLibMessageParameters) => m( + this.HINT_UnreachableRule, + `This rule will never be matched as the rule on line ${o.p?.[0]} takes precedence` + ); static WARN_VirtualKeyInOutput = SevWarn | 0x0AF; static Warn_VirtualKeyInOutput = () => m(this.WARN_VirtualKeyInOutput, `Virtual keys are not supported in output`); @@ -744,17 +733,6 @@ export class KmnCompilerMessages { static FATAL_BufferOverflow = SevFatal | 0x0C0; static Fatal_BufferOverflow = () => m(this.FATAL_BufferOverflow, `The compiler memory buffer overflowed`); - static FATAL_Break = SevFatal | 0x0C1; - static Fatal_Break = () => m(this.FATAL_Break, `Compiler interrupted by user`); -}; - -export function mapErrorFromKmcmplib(line: number, code: number, msg: string): CompilerEvent { - const severity = LogLevelToSeverity[code & LogLevel.LEVEL_MASK]; - const baseCode = code & LogLevel.CODE_MASK; - const event: CompilerEvent = { - line: line, - code: severity | CompilerErrorNamespace.KmnCompiler | baseCode, - message: msg - }; - return event; + // static FATAL_Break = SevFatal | 0x0C1; + // static Fatal_Break = () => m(this.FATAL_Break, `Compiler interrupted by user`); }; diff --git a/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts b/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts index e5d4ed3ec3..448b6bd6ac 100644 --- a/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts +++ b/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts @@ -49,7 +49,9 @@ export class KmwCompilerMessages extends KmnCompilerMessages { static Hint_TouchLayoutUsesUnsupportedGesturesDownlevel = (o:{keyId:string}) => m(this.HINT_TouchLayoutUsesUnsupportedGesturesDownlevel, `The touch layout uses a flick or multi-tap gesture on key ${def(o.keyId)}, which is only available on version 17.0+ of Keyman`); - static INFO_MinimumEngineVersion = SevInfo | 0x0006; - static Info_MinimumEngineVersion = (o:{version:string}) => m(this.INFO_MinimumEngineVersion, - `The compiler has assigned a minimum web engine version of ${o.version} based on features used in this keyboard`); + static INFO_MinimumWebEngineVersion = SevInfo | 0x0006; + static Info_MinimumWebEngineVersion = (o:{version:string}) => m( + this.INFO_MinimumWebEngineVersion, + `The compiler has assigned a minimum web engine version of ${o.version} based on features used in this keyboard` + ); }; diff --git a/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler.ts b/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler.ts index ae67b731e0..65f2111ecf 100644 --- a/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler.ts +++ b/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler.ts @@ -412,7 +412,7 @@ export function WriteCompiledKeyboard( if((fk.flags & KMX.KMXFile.KF_AUTOMATICVERSION) == KMX.KMXFile.KF_AUTOMATICVERSION) { // Note: the KeymanWeb compiler is responsible for reporting minimum // version for the web targets - callbacks.reportMessage(KmwCompilerMessages.Info_MinimumEngineVersion({version:minVer})); + callbacks.reportMessage(KmwCompilerMessages.Info_MinimumWebEngineVersion({version:minVer})); } return resultPrefix + resultMinVer + result; diff --git a/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_group.kmn b/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_group.kmn index 8382b5ea7f..9f5be31f17 100644 --- a/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_group.kmn +++ b/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_group.kmn @@ -1,7 +1,7 @@ c Description: Verifies that kmcmplib picks up on duplicated groups with Unicode names, c and that the Unicode names are correctly reported in error messages in UTF-8 -store(&NAME) 'cerr_duplicate_group' +store(&NAME) 'error_duplicate_group' store(&VERSION) '9.0' begin unicode > use(ខ្មែរ) diff --git a/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_store.kmn b/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_store.kmn index 14d27d5be6..0f520a3d74 100644 --- a/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_store.kmn +++ b/developer/src/kmc-kmn/test/fixtures/invalid-keyboards/error_duplicate_store.kmn @@ -1,7 +1,7 @@ c Description: Verifies that kmcmplib picks up on duplicated stores with Unicode names, c and that the Unicode names are correctly reported in error messages in UTF-8 -store(&NAME) 'cerr_duplicate_store' +store(&NAME) 'error_duplicate_store' store(&VERSION) '9.0' begin unicode > use(ខ្មែរ) diff --git a/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts b/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts index 0e7902a508..3e9cbaba87 100644 --- a/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts +++ b/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts @@ -87,10 +87,9 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); - assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); - // The min version message from the .kmn compiler is generic 208A INFO_Info; + assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); // we expect only 1 of the info messages -- for the .kmx target (not 2) - assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_Info).length, 1); + assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_MinimumCoreEngineVersion).length, 1); const data = new TextDecoder('utf-8').decode(result.artifacts.js.data); assert.match(data, /KMINVER="15.0"/, `Could not find expected 'KMINVER="15.0"'`); @@ -101,9 +100,8 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNull(result); - // The min version message from the .kmn compiler is generic 208A INFO_Info - assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_Info)); - assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_MinimumCoreEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.ERROR_TouchLayoutIdentifierRequires15)); }); @@ -113,9 +111,8 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); // only a warning, so output is generated - // The min version message from the .kmn compiler is generic 208A INFO_Info - assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_Info)); - assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_MinimumCoreEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb)); }); @@ -125,10 +122,9 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); - // The min version message from the .kmn compiler is generic 208A INFO_Info; // we expect only 1 of the info messages -- for the .kmx target (not 2) - assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_Info).length, 1); - assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_MinimumCoreEngineVersion).length, 1); + assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb)); const data = new TextDecoder('utf-8').decode(result.artifacts.js.data); @@ -142,10 +138,9 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); - assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); - // The min version message from the .kmn compiler is generic 208A INFO_Info; + assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); // we expect only 1 of the info messages -- for the .kmx target (not 2) - assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_Info).length, 1); + assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_MinimumCoreEngineVersion).length, 1); const data = new TextDecoder('utf-8').decode(result.artifacts.js.data); assert.match(data, /KMINVER="14.0"/, `Could not find expected 'KMINVER="14.0"'`); @@ -157,9 +152,8 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNull(result); - // The min version message from the .kmn compiler is generic 208A INFO_Info - assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_Info)); - assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_MinimumCoreEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.ERROR_140FeatureOnlyContextAndNotAnyWeb)); }); @@ -168,10 +162,9 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); - assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); - // The min version message from the .kmn compiler is generic 208A INFO_Info; + assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); // we expect only 1 of the info messages -- for the .kmx target (not 2) - assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_Info).length, 1); + assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_MinimumCoreEngineVersion).length, 1); const data = new TextDecoder('utf-8').decode(result.artifacts.js.data); assert.match(data, /KMINVER="14.0"/, `Could not find expected 'KMINVER="14.0"'`); @@ -182,9 +175,8 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); - // The min version message from the .kmn compiler is generic 208A INFO_Info - assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_Info)); - assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_MinimumCoreEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.WARN_TouchLayoutSpecialLabelOnNormalKey)); }); @@ -193,10 +185,9 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); - assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); - // The min version message from the .kmn compiler is generic 208A INFO_Info; + assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); // we expect only 1 of the info messages -- for the .kmx target (not 2) - assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_Info).length, 1); + assert.equal(callbacks.messages.filter(item => item.code == KmnCompilerMessages.INFO_MinimumCoreEngineVersion).length, 1); const data = new TextDecoder('utf-8').decode(result.artifacts.js.data); assert.match(data, /KMINVER="17.0"/, `Could not find expected 'KMINVER="17.0"'`); @@ -207,9 +198,8 @@ describe('KeymanWeb Compiler', function() { let result = await kmnCompiler.run(filenames.source, null); assert.isNotNull(result); - // The min version message from the .kmn compiler is generic 208A INFO_Info - assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_Info)); - assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmnCompilerMessages.INFO_MinimumCoreEngineVersion)); + assert.isFalse(callbacks.hasMessage(KmwCompilerMessages.INFO_MinimumWebEngineVersion)); assert.isTrue(callbacks.hasMessage(KmwCompilerMessages.HINT_TouchLayoutUsesUnsupportedGesturesDownlevel)); }); diff --git a/developer/src/kmc-kmn/test/test-messages.ts b/developer/src/kmc-kmn/test/test-messages.ts index df86c7e1dc..ea697a0174 100644 --- a/developer/src/kmc-kmn/test/test-messages.ts +++ b/developer/src/kmc-kmn/test/test-messages.ts @@ -1,10 +1,10 @@ import 'mocha'; import { assert } from 'chai'; -import { KmnCompilerMessages } from '../src/compiler/kmn-compiler-messages.js'; +import { KmnCompilerMessageRanges, KmnCompilerMessages } from '../src/compiler/kmn-compiler-messages.js'; import { TestCompilerCallbacks, verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; import { makePathToFixture } from './helpers/index.js'; import { KmnCompiler } from '../src/main.js'; -import { CompilerErrorNamespace } from '@keymanapp/common-types'; +import { CompilerErrorMask, CompilerErrorNamespace } from '@keymanapp/common-types'; describe('KmnCompilerMessages', function () { const callbacks = new TestCompilerCallbacks(); @@ -13,6 +13,69 @@ describe('KmnCompilerMessages', function () { return verifyCompilerMessagesObject(KmnCompilerMessages, CompilerErrorNamespace.KmnCompiler); }); + it('should have a 1:1 correspondence with kmn_compiler_errors.h', function() { + + const headerFilename = 'kmn_compiler_errors.h'; + const tsFilename = 'kmn-compiler-messages.ts'; + + // For each message declared in KmnCompilerMessages, look for a + // corresponding message in kmn_compiler_errors.h + const headerPath = makePathToFixture(`../../../common/include/${headerFilename}`); + + // Matching the following line pattern from kmn_compiler_errors.h: + // + // FATAL_BadCallParams = SevFatal | 0x002, + const messageRegex = /^\s+((FATAL|ERROR|WARN|HINT|INFO)_[a-z0-9_]+)\s+=\s+Sev(Fatal|Error|Warn|Hint|Info)\s+\|\s+0x([0-9a-f]+)/i; + + // Convert matching lines into array of message code data + const cppMessages = callbacks.fs.readFileSync(headerPath, 'utf-8') + .replace(/\r/g, '') + .split('\n') + .filter(line => line.match(messageRegex)) // filter first, run regex twice, ;-) + .map(line => { + const m = line.match(messageRegex); + return { name: m[1], nameSeverity: m[2], maskSeverity: m[3], code: parseInt(m[4],16), found: false } + }); + + const cppMessagesByName: {[index:string]: {name: string, nameSeverity: string, maskSeveity: string, code: number}} = cppMessages + .reduce((obj, m) => {obj[m.name] = m; return obj}, {} as any); + + // We validate that the nameSeverity and maskSeverity line up, as a sanity + // check. This conceptually belongs in kmcmplib tests, but much easier to + // achieve here + cppMessages.forEach(m => { + assert.strictEqual(m.maskSeverity.toUpperCase(), m.nameSeverity, `${headerFilename} has mismatching severity for ${m.name} and ${m.maskSeverity}`) + }); + + // Use same pattern as verifyCompilerMessagesObject to get list of messages + // from KmnCompilerMessages + const keys = Object.keys(KmnCompilerMessages); + const m = KmnCompilerMessages as Record; + + for(const key of keys) { + // Verify each object member matches the pattern we expect + if(typeof m[key] == 'number') { + + if((m[key] & CompilerErrorMask.BaseError) < KmnCompilerMessageRanges.RANGE_KMN_COMPILER_MIN || + (m[key] & CompilerErrorMask.BaseError) > KmnCompilerMessageRanges.RANGE_KMN_COMPILER_MAX) { + // Message is not from kmcmplib + continue; + } + + const cppMessage = cppMessagesByName[key]; + assert.isDefined(cppMessage, `${key} in ${tsFilename} not found in ${headerFilename}`); + assert.equal(cppMessage.name, key, `${key} name in ${tsFilename} does not precisely match ${headerFilename}`); + assert.equal(cppMessage.code, m[key] & CompilerErrorMask.BaseError, `${key} in ${tsFilename} has a different value than ${headerFilename}`); + + // Remove the entry so we can spot unpaired messages afterwards + delete cppMessagesByName[key]; + } + } + + // Ensure there are no remaining messages in kmn_compiler_errors.h + assert.isEmpty(Object.keys(cppMessagesByName), `${headerFilename} has entries not found in ${tsFilename}: ${JSON.stringify(cppMessagesByName)}`); + }); + // // Message tests // diff --git a/developer/src/kmc-kmn/tsconfig.json b/developer/src/kmc-kmn/tsconfig.json index 50ddcc28d7..2095229bff 100644 --- a/developer/src/kmc-kmn/tsconfig.json +++ b/developer/src/kmc-kmn/tsconfig.json @@ -12,4 +12,9 @@ "src/**/*.ts", "src/import/kmcmplib/wasm-host.js" ], + "references": [ + { "path": "../../../common/web/types/" }, + { "path": "../../../common/web/keyman-version/" }, + { "path": "../common/web/utils/" }, + ] } diff --git a/developer/src/kmc-ldml/test/tsconfig.json b/developer/src/kmc-ldml/test/tsconfig.json index 08c87ab0f5..cda7185360 100644 --- a/developer/src/kmc-ldml/test/tsconfig.json +++ b/developer/src/kmc-ldml/test/tsconfig.json @@ -13,6 +13,10 @@ "./helpers/index.ts" ], "references": [ + { "path": "../../../../common/web/keyman-version" }, + { "path": "../../../../common/web/types/" }, + { "path": "../../../../common/tools/hextobin/" }, + { "path": "../../common/web/test-helpers/" }, { "path": "../" } ] } \ No newline at end of file diff --git a/developer/src/kmc-ldml/tsconfig.json b/developer/src/kmc-ldml/tsconfig.json index 2039577391..36d915f074 100644 --- a/developer/src/kmc-ldml/tsconfig.json +++ b/developer/src/kmc-ldml/tsconfig.json @@ -9,4 +9,10 @@ "include": [ "src/**/*.ts" ], + "references": [ + { "path": "../../../common/web/keyman-version" }, + { "path": "../../../common/web/types/" }, + { "path": "../kmc-kmn/" }, + { "path": "../../../core/include/ldml/"}, + ] } diff --git a/developer/src/kmc-model-info/test/tsconfig.json b/developer/src/kmc-model-info/test/tsconfig.json index 5f74a1dc19..e16b935aa4 100644 --- a/developer/src/kmc-model-info/test/tsconfig.json +++ b/developer/src/kmc-model-info/test/tsconfig.json @@ -15,5 +15,7 @@ ], "references": [ { "path": "../" }, + { "path": "../../common/web/test-helpers/" }, + { "path": "../../kmc-package/" }, ] } \ No newline at end of file diff --git a/developer/src/kmc-model-info/tsconfig.json b/developer/src/kmc-model-info/tsconfig.json index c80e506eee..24475de019 100644 --- a/developer/src/kmc-model-info/tsconfig.json +++ b/developer/src/kmc-model-info/tsconfig.json @@ -8,4 +8,9 @@ "include": [ "src/**/*.ts" ], + "references": [ + { "path": "../../../common/web/types" }, + { "path": "../../../common/models/types" }, + { "path": "../common/web/utils" }, + ] } diff --git a/developer/src/kmc-model/test/tsconfig.json b/developer/src/kmc-model/test/tsconfig.json index 7f58b73d42..1b1ca1668f 100644 --- a/developer/src/kmc-model/test/tsconfig.json +++ b/developer/src/kmc-model/test/tsconfig.json @@ -17,5 +17,6 @@ ], "references": [ { "path": "../" }, + { "path": "../../common/web/test-helpers/" }, ] } \ No newline at end of file diff --git a/developer/src/kmc-model/tsconfig.json b/developer/src/kmc-model/tsconfig.json index 43bd82b8f5..724ebd74d0 100644 --- a/developer/src/kmc-model/tsconfig.json +++ b/developer/src/kmc-model/tsconfig.json @@ -10,4 +10,9 @@ "include": [ "src/**/*.ts" ], + "references": [ + { "path": "../../../common/web/keyman-version" }, + { "path": "../../../common/models/types" }, + { "path": "../../../common/web/types" }, + ] } diff --git a/developer/src/kmc-package/test/tsconfig.json b/developer/src/kmc-package/test/tsconfig.json index 47227f07e3..62904114c8 100644 --- a/developer/src/kmc-package/test/tsconfig.json +++ b/developer/src/kmc-package/test/tsconfig.json @@ -14,5 +14,8 @@ ], "references": [ { "path": "../" }, + { "path": "../../../../common/web/types" }, + { "path": "../../../../common/web/keyman-version" }, + { "path": "../../common/web/test-helpers/" }, ] } \ No newline at end of file diff --git a/developer/src/kmc-package/tsconfig.json b/developer/src/kmc-package/tsconfig.json index 78fd3c3fb7..0ab78a91ff 100644 --- a/developer/src/kmc-package/tsconfig.json +++ b/developer/src/kmc-package/tsconfig.json @@ -9,4 +9,8 @@ "include": [ "src/**/*.ts", ], + "references": [ + { "path": "../../../common/web/keyman-version" }, + { "path": "../../../common/web/types" }, + ] } diff --git a/developer/src/kmc/test/tsconfig.json b/developer/src/kmc/test/tsconfig.json index 6c7d251747..3d0d6eb4f6 100644 --- a/developer/src/kmc/test/tsconfig.json +++ b/developer/src/kmc/test/tsconfig.json @@ -12,6 +12,8 @@ "./helpers/index.ts", ], "references": [ + { "path": "../../../../common/web/types/" }, + { "path": "../../common/web/test-helpers/" }, { "path": "../" } ] } \ No newline at end of file diff --git a/developer/src/kmc/tsconfig.json b/developer/src/kmc/tsconfig.json index 53c0c34306..cf78a8a775 100644 --- a/developer/src/kmc/tsconfig.json +++ b/developer/src/kmc/tsconfig.json @@ -9,4 +9,15 @@ "include": [ "src/**/*.ts" ], + "references": [ + { "path": "../../../common/web/keyman-version" }, + { "path": "../../../common/web/types" }, + { "path": "../kmc-analyze" }, + { "path": "../kmc-keyboard-info" }, + { "path": "../kmc-kmn" }, + { "path": "../kmc-ldml" }, + { "path": "../kmc-model" }, + { "path": "../kmc-model-info" }, + { "path": "../kmc-package" }, + ] } diff --git a/developer/src/kmcmplib/include/kmcmplibapi.h b/developer/src/kmcmplib/include/kmcmplibapi.h index eb7a9b549c..c41ba53eaa 100644 --- a/developer/src/kmcmplib/include/kmcmplibapi.h +++ b/developer/src/kmcmplib/include/kmcmplibapi.h @@ -53,6 +53,14 @@ struct KMCMP_COMPILER_RESULT_EXTRA_GROUP { std::string name; }; +struct KMCMP_COMPILER_RESULT_MESSAGE { + unsigned int errorCode; + int lineNumber; + int columnNumber; + std::string filename; + std::vector parameters; +}; + #define COMPILETARGETS_KMX 0x01 #define COMPILETARGETS_JS 0x02 #define COMPILETARGETS__MASK 0x03 @@ -75,19 +83,8 @@ struct KMCMP_COMPILER_RESULT { /** * @param szText UTF-8 string */ -typedef int (*kmcmp_CompilerMessageProc)(int line, uint32_t dwMsgCode, const char* szText, void* context); - -// parameters in UTF-8 -// TODO typical usage: -// if(!kmcmp_LoadFileProc("filename.ico", "/tmp/filename.kmn", nullptr, &size)) { -// return error; -// } -// buf = new unsigned char[size]; -// if(!kmcmp_LoadFileProc("filename.ico", "/tmp/filename.kmn", buf, &size)) { -// delete[] buf; -// return error; -// } -typedef bool (*kmcmp_LoadFileProc)(const char* loadFilename, const char* baseFilename, void* buffer, int* bufferSize, void* context); +typedef void (*kmcmp_CompilerMessageProc)(const KMCMP_COMPILER_RESULT_MESSAGE &message, void* context); +typedef const std::vector (*kmcmp_LoadFileProc)(const std::string& loadFilename, const std::string& baseFilename); /** * @param pszInfile UTF-8 path to file.kmn diff --git a/developer/src/kmcmplib/src/CasedKeys.cpp b/developer/src/kmcmplib/src/CasedKeys.cpp index 759a497d14..0a0508f11a 100644 --- a/developer/src/kmcmplib/src/CasedKeys.cpp +++ b/developer/src/kmcmplib/src/CasedKeys.cpp @@ -24,7 +24,7 @@ KMX_DWORD VerifyCasedKeys(PFILE_STORE sp) { if (kmcmp::FMnemonicLayout) { // The &CasedKeys system store is not supported for // mnemonic layouts in 14.0 - return CERR_CasedKeysNotSupportedWithMnemonicLayout; + return KmnCompilerMessages::ERROR_CasedKeysNotSupportedWithMnemonicLayout; } // We will rewrite this store with virtual keys @@ -37,20 +37,20 @@ KMX_DWORD VerifyCasedKeys(PFILE_STORE sp) { KMX_UINT key = 0, shift = 0; if (*p != UC_SENTINEL) { if (!kmcmp::MapUSCharToVK(*p, &key, &shift)) { - return CERR_CasedKeysMustContainOnlyVirtualKeys; + return KmnCompilerMessages::ERROR_CasedKeysMustContainOnlyVirtualKeys; } if (shift & K_SHIFTFLAG) { - return CERR_CasedKeysMustNotIncludeShiftStates; + return KmnCompilerMessages::ERROR_CasedKeysMustNotIncludeShiftStates; } } else { if (*(p + 1) != CODE_EXTENDED) { - return CERR_CasedKeysMustContainOnlyVirtualKeys; + return KmnCompilerMessages::ERROR_CasedKeysMustContainOnlyVirtualKeys; } shift = *(p + 2); key = *(p + 3); if (shift != ISVIRTUALKEY) { - return CERR_CasedKeysMustNotIncludeShiftStates; + return KmnCompilerMessages::ERROR_CasedKeysMustNotIncludeShiftStates; } } *q++ = UC_SENTINEL; @@ -66,7 +66,7 @@ KMX_DWORD VerifyCasedKeys(PFILE_STORE sp) { delete[] sp->dpString; sp->dpString = buf; - return CERR_None; + return STATUS_Success; } KMX_DWORD ExpandCapsRulesForGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) { @@ -76,14 +76,14 @@ KMX_DWORD ExpandCapsRulesForGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) { if (kmcmp::FMnemonicLayout) { // The &CasedKeys system store is not supported for // mnemonic layouts in 14.0 - return CERR_None; + return STATUS_Success; } PFILE_STORE sp = FindSystemStore(fk, TSS_CASEDKEYS); if (!sp) { // If there is no &CasedKeys system store, then we do not // process the key - return CERR_None; + return STATUS_Success; } KMX_DWORD msg; @@ -92,11 +92,11 @@ KMX_DWORD ExpandCapsRulesForGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) { // dereference the array every call int cxKeyArray = gp->cxKeyArray; for (int i = 0; i < cxKeyArray; i++) { - if ((msg = ExpandCapsRule(gp, &gp->dpKeyArray[i], sp)) != CERR_None) { + if ((msg = ExpandCapsRule(gp, &gp->dpKeyArray[i], sp)) != STATUS_Success) { return msg; } } - return CERR_None; + return STATUS_Success; } KMX_DWORD ExpandCapsRule(PFILE_GROUP gp, PFILE_KEY kpp, PFILE_STORE sp) { @@ -106,13 +106,13 @@ KMX_DWORD ExpandCapsRule(PFILE_GROUP gp, PFILE_KEY kpp, PFILE_STORE sp) { if (shift == 0) { // Convert US key cap to a virtual key if (!kmcmp::MapUSCharToVK(kpp->Key, &key, &shift)) { - return CERR_None; + return STATUS_Success; } } if (shift & (CAPITALFLAG | NOTCAPITALFLAG)) { // Don't attempt expansion if either Caps Lock flag is specified in the key rule - return CERR_None; + return STATUS_Success; } PKMX_WCHAR p = sp->dpString; @@ -125,13 +125,13 @@ KMX_DWORD ExpandCapsRule(PFILE_GROUP gp, PFILE_KEY kpp, PFILE_STORE sp) { if (!*p) { // This key is not modified by Caps Lock - return CERR_None; + return STATUS_Success; } // This key is modified by Caps Lock, so we need to duplicate this rule int offset = (int)(kpp - gp->dpKeyArray); if(!resizeKeyArray(gp)) { - return CERR_CannotAllocateMemory; + return KmnCompilerMessages::FATAL_CannotAllocateMemory; } kpp = &gp->dpKeyArray[offset]; gp->cxKeyArray++; @@ -149,5 +149,5 @@ KMX_DWORD ExpandCapsRule(PFILE_GROUP gp, PFILE_KEY kpp, PFILE_STORE sp) { kpp->Key = key; kpp->ShiftFlags = shift | NOTCAPITALFLAG; - return CERR_None; + return STATUS_Success; } diff --git a/developer/src/kmcmplib/src/CheckForDuplicates.cpp b/developer/src/kmcmplib/src/CheckForDuplicates.cpp index 56b6195fb4..9e5d63b9ef 100644 --- a/developer/src/kmcmplib/src/CheckForDuplicates.cpp +++ b/developer/src/kmcmplib/src/CheckForDuplicates.cpp @@ -10,7 +10,7 @@ #include "CheckForDuplicates.h" -KMX_DWORD CheckForDuplicateGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) noexcept { +KMX_BOOL CheckForDuplicateGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) noexcept { KMX_DWORD i; PFILE_GROUP gp0 = fk->dpGroupArray; for (i = 0; i < fk->cxGroupArray; i++, gp0++) { @@ -18,18 +18,21 @@ KMX_DWORD CheckForDuplicateGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) noexcept { continue; } if (u16icmp(gp0->szName, gp->szName) == 0) { - snprintf(ErrExtraLIB, ERR_EXTRA_LIB_LEN, " Group '%s' declared on line %d", string_from_u16string(gp->szName).c_str(), gp0->Line); - return CERR_DuplicateGroup; + ReportCompilerMessage(KmnCompilerMessages::ERROR_DuplicateGroup, { + /*groupName*/ string_from_u16string(gp->szName), + /*lineNumber*/ std::to_string(gp0->Line) + }); + return FALSE; } } - return CERR_None; + return TRUE; } -KMX_DWORD CheckForDuplicateStore(PFILE_KEYBOARD fk, PFILE_STORE sp) noexcept { +KMX_BOOL CheckForDuplicateStore(PFILE_KEYBOARD fk, PFILE_STORE sp) noexcept { if (!sp->szName[0]) { // Stores with zero length names are reserved system stores. // They cannot be defined in user code. This is not an issue. - return CERR_None; + return TRUE; } KMX_DWORD i; PFILE_STORE sp0 = fk->dpStoreArray; @@ -38,9 +41,12 @@ KMX_DWORD CheckForDuplicateStore(PFILE_KEYBOARD fk, PFILE_STORE sp) noexcept { continue; } if (u16icmp(sp0->szName, sp->szName) == 0) { - snprintf(ErrExtraLIB, ERR_EXTRA_LIB_LEN, " Store '%s' declared on line %d", string_from_u16string(sp0->szName).c_str(), sp0->line); - return CERR_DuplicateStore; + ReportCompilerMessage(KmnCompilerMessages::ERROR_DuplicateStore, { + /*storeName*/ string_from_u16string(sp0->szName), + /*lineNumber*/ std::to_string(sp0->line) + }); + return FALSE; } } - return CERR_None; + return TRUE; } diff --git a/developer/src/kmcmplib/src/CheckForDuplicates.h b/developer/src/kmcmplib/src/CheckForDuplicates.h index 20789dd5e2..e338f290f5 100644 --- a/developer/src/kmcmplib/src/CheckForDuplicates.h +++ b/developer/src/kmcmplib/src/CheckForDuplicates.h @@ -1,4 +1,4 @@ #pragma once -KMX_DWORD CheckForDuplicateGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) noexcept; -KMX_DWORD CheckForDuplicateStore(PFILE_KEYBOARD fk, PFILE_STORE sp) noexcept; +KMX_BOOL CheckForDuplicateGroup(PFILE_KEYBOARD fk, PFILE_GROUP gp) noexcept; +KMX_BOOL CheckForDuplicateStore(PFILE_KEYBOARD fk, PFILE_STORE sp) noexcept; diff --git a/developer/src/kmcmplib/src/CheckNCapsConsistency.cpp b/developer/src/kmcmplib/src/CheckNCapsConsistency.cpp index c86c62702e..a170419e02 100644 --- a/developer/src/kmcmplib/src/CheckNCapsConsistency.cpp +++ b/developer/src/kmcmplib/src/CheckNCapsConsistency.cpp @@ -33,7 +33,7 @@ * * @param fk Keyboard to check */ -bool CheckNCapsConsistency(PFILE_KEYBOARD fk) { +void CheckNCapsConsistency(PFILE_KEYBOARD fk) { struct CapsUsage { int ncaps_line, caps_line, neither_line; }; @@ -87,13 +87,11 @@ bool CheckNCapsConsistency(PFILE_KEYBOARD fk) { if (caps_ncaps_usage[i].neither_line && (caps_ncaps_usage[i].caps_line || caps_ncaps_usage[i].ncaps_line)) { // We set the current line to one needing work: the developer should add the NCAPS flag kmcmp::currentLine = caps_ncaps_usage[i].neither_line; - AddWarningBool(CWARN_KeyShouldIncludeNCaps); + ReportCompilerMessage(KmnCompilerMessages::WARN_KeyShouldIncludeNCaps); } } delete[] caps_ncaps_usage; kmcmp::currentLine = oldCurrentLine; - - return TRUE; } diff --git a/developer/src/kmcmplib/src/CheckNCapsConsistency.h b/developer/src/kmcmplib/src/CheckNCapsConsistency.h index 50fa744c4a..913ab87fa4 100644 --- a/developer/src/kmcmplib/src/CheckNCapsConsistency.h +++ b/developer/src/kmcmplib/src/CheckNCapsConsistency.h @@ -2,4 +2,4 @@ #include -bool CheckNCapsConsistency(PFILE_KEYBOARD fk); +void CheckNCapsConsistency(PFILE_KEYBOARD fk); diff --git a/developer/src/kmcmplib/src/CompMsg.cpp b/developer/src/kmcmplib/src/CompMsg.cpp deleted file mode 100644 index b41409b0db..0000000000 --- a/developer/src/kmcmplib/src/CompMsg.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include -#include - -std::map CompilerErrorMap = { - { CERR_InvalidLayoutLine , "Invalid 'layout' command"}, - { CERR_NoVersionLine , "No version line found for file"}, - { CERR_InvalidGroupLine , "Invalid 'group' command"}, - { CERR_InvalidStoreLine , "Invalid 'store' command"}, - { CERR_InvalidCodeInKeyPartOfRule , "Invalid command or code found in key part of rule"}, - { CERR_InvalidDeadkey , "Invalid 'deadkey' or 'dk' command"}, - { CERR_InvalidValue , "Invalid value in extended string"}, - { CERR_ZeroLengthString , "A string of zero characters was found"}, - { CERR_TooManyIndexToKeyRefs , "Too many index commands refering to key string"}, - { CERR_UnterminatedString , "Unterminated string in line"}, - { CERR_StringInVirtualKeySection , "extend string illegal in virtual key section"}, - { CERR_AnyInVirtualKeySection , "'any' command is illegal in virtual key section"}, - { CERR_InvalidAny , "Invalid 'any' command"}, - { CERR_StoreDoesNotExist , "Store referenced does not exist"}, - { CERR_BeepInVirtualKeySection , "'beep' command is illegal in virtual key section"}, - { CERR_IndexInVirtualKeySection , "'index' command is illegal in virtual key section"}, - { CERR_BadCallParams , "CompileKeyboardFile was called with bad parameters"}, - { CERR_InfileNotExist , "Cannot find the input file"}, - // { CERR_CannotCreateOutfile , "Cannot open output file for writing"}, unused - { CERR_UnableToWriteFully , "Unable to write the file completely"}, - { CERR_CannotReadInfile , "Cannot read the input file"}, - { CERR_SomewhereIGotItWrong , "Internal error: contact Keyman"}, - { CERR_BufferOverflow , "The compiler memory buffer overflowed"}, - { CERR_Break , "Compiler interrupted by user"}, - { CERR_CannotAllocateMemory , "Out of memory"}, - { CERR_InvalidBitmapLine , "Invalid 'bitmaps' command"}, - { CERR_CannotReadBitmapFile , "Cannot open the bitmap or icon file for reading"}, - { CERR_IndexDoesNotPointToAny , "An index() in the output does not have a corresponding any() statement"}, - { CERR_ReservedCharacter , "A reserved character was found"}, - { CERR_InvalidCharacter , "A character was found that is outside the valid Unicode range (U+0000 - U+10FFFF)"}, - { CERR_InvalidCall , "The 'call' command is invalid"}, - { CERR_CallInVirtualKeySection , "'call' command is illegal in virtual key section"}, - { CERR_CodeInvalidInKeyStore , "The command is invalid inside a store that is used in a key part of the rule"}, - { CERR_CannotLoadIncludeFile , "Cannot load the included file: it is either invalid or does not exist"}, - { CERR_60FeatureOnly_EthnologueCode , "EthnologueCode system store requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_MnemonicLayout , "MnemonicLayout functionality requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_OldCharPosMatching , "OldCharPosMatching system store requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_NamedCodes , "Named character constants requires VERSION 6.0 or higher"}, - { CERR_60FeatureOnly_Contextn , "Context(n) requires VERSION 6.0 or higher"}, - { CERR_501FeatureOnly_Call , "Call() requires VERSION 5.01 or higher"}, - { CERR_InvalidNamedCode , "Invalid named code constant"}, - { CERR_InvalidSystemStore , "Invalid system store name found"}, - { CERR_60FeatureOnly_VirtualCharKey , "Virtual character keys require VERSION 6.0 or higher"}, - { CERR_VersionAlreadyIncluded , "Only one VERSION or store(version) line allowed in a source file."}, - { CERR_70FeatureOnly , "This feature requires store(version) '7.0' or higher"}, - { CERR_80FeatureOnly , "This feature requires store(version) '8.0' or higher"}, - { CERR_InvalidInVirtualKeySection , "This statement is not valid in a virtual key section"}, - { CERR_InvalidIf , "The if() statement is not valid"}, - { CERR_InvalidReset , "The reset() statement is not valid"}, - { CERR_InvalidSet , "The set() statement is not valid"}, - { CERR_InvalidSave , "The save() statement is not valid"}, - { CERR_InvalidEthnologueCode , "Invalid ethnologuecode format"}, - { CERR_90FeatureOnly_IfSystemStores , "if(store) requires store(version) '9.0' or higher"}, - { CERR_IfSystemStore_NotFound , "System store in if() not found"}, - { CERR_90FeatureOnly_SetSystemStores , "set(store) requires store(version) '9.0' or higher"}, - { CERR_SetSystemStore_NotFound , "System store in set() not found"}, - { CERR_90FeatureOnlyVirtualKeyDictionary , "Custom virtual key names require store(version) '9.0'"}, - { CERR_InvalidIndex , "Invalid 'index' command"}, - { CERR_OutsInVirtualKeySection , "'outs' command is illegal in virtual key section"}, - { CERR_InvalidOuts , "Invalid 'outs' command"}, - { CERR_ContextInVirtualKeySection , "'context' command is illegal in virtual key section"}, - { CERR_InvalidUse , "Invalid 'use' command"}, - { CERR_GroupDoesNotExist , "Group does not exist"}, - { CERR_VirtualKeyNotAllowedHere , "Virtual key is not allowed here"}, - { CERR_InvalidSwitch , "Invalid 'switch' command"}, - { CERR_NoTokensFound , "No tokens found in line"}, - { CERR_InvalidLineContinuation , "Invalid line continuation"}, - { CERR_LineTooLong , "Line too long"}, - { CERR_InvalidCopyright , "Invalid 'copyright' command"}, - { CERR_CodeInvalidInThisSection , "This line is invalid in this section of the file"}, - { CERR_InvalidMessage , "Invalid 'message' command"}, - { CERR_InvalidLanguageName , "Invalid 'languagename' command"}, - { CERR_EndOfFile , "(no error - reserved code)"}, - { CERR_InvalidToken , "Invalid token found"}, - { CERR_InvalidBegin , "Invalid 'begin' command"}, - { CERR_InvalidName , "Invalid 'name' command"}, - { CERR_InvalidVersion , "Invalid 'version' command"}, - { CERR_InvalidLanguageLine , "Invalid 'language' command"}, - { CERR_LayoutButNoLanguage , "Layout command found but no language command"}, - { CERR_CannotCreateTempfile , "Cannot create temp file"}, - { CERR_90FeatureOnlyLayoutFile , "Touch layout file reference requires store(version) '9.0' or higher"}, - { CERR_90FeatureOnlyKeyboardVersion , "KeyboardVersion system store requires store(version) '9.0' or higher"}, - { CERR_KeyboardVersionFormatInvalid , "KeyboardVersion format is invalid, expecting dot-separated integers"}, - { CERR_ContextExHasInvalidOffset , "context() statement has offset out of range"}, - { CERR_90FeatureOnlyEmbedCSS , "Embedding CSS requires store(version) '9.0' or higher"}, - { CERR_90FeatureOnlyTargets , "TARGETS system store requires store(version) '9.0' or higher"}, - { CERR_ContextAndIndexInvalidInMatchNomatch , "context and index statements cannot be used in a match or nomatch statement"}, - { CERR_140FeatureOnlyContextAndNotAnyWeb , "For web and touch platforms, context() statement referring to notany() requires store(version) '14.0' or higher"}, - { CERR_ExpansionMustFollowCharacterOrVKey , "An expansion must follow a character or a virtual key"}, - { CERR_VKeyExpansionMustBeFollowedByVKey , "A virtual key expansion must be terminated by a virtual key"}, - { CERR_CharacterExpansionMustBeFollowedByCharacter , "A character expansion must be terminated by a character key"}, - { CERR_VKeyExpansionMustUseConsistentShift , "A virtual key expansion must use the same shift state for both terminators"}, - { CERR_ExpansionMustBePositive , "An expansion must have positive difference (i.e. A-Z, not Z-A)"}, - { CERR_CasedKeysMustContainOnlyVirtualKeys , "The &CasedKeys system store must contain only virtual keys or characters found on a US English keyboard"}, - { CERR_CasedKeysMustNotIncludeShiftStates , "The &CasedKeys system store must not include shift states"}, - { CERR_CasedKeysNotSupportedWithMnemonicLayout , "The &CasedKeys system store is not supported with mnemonic layouts"}, - { CERR_CannotUseReadWriteGroupFromReadonlyGroup , "Group used from a readonly group must also be readonly"}, - { CERR_StatementNotPermittedInReadonlyGroup , "Statement is not permitted in output of readonly group"}, - { CERR_OutputInReadonlyGroup , "Output is not permitted in a readonly group"}, - { CERR_NewContextGroupMustBeReadonly , "Group used in begin newContext must be readonly"}, - { CERR_PostKeystrokeGroupMustBeReadonly , "Group used in begin postKeystroke must be readonly"}, - { CERR_DuplicateGroup , "A group with this name has already been defined."}, - { CERR_DuplicateStore , "A store with this name has already been defined."}, - { CERR_RepeatedBegin , "Begin has already been set"}, - { CERR_VirtualKeyInContext , "Virtual keys are not permitted in context"}, - { CERR_OutsTooLong , "Store cannot be inserted with outs() as it makes the extended string too long" }, - { CERR_ExtendedStringTooLong , "Extended string is too long" }, - { CERR_VirtualKeyExpansionTooLong , "Virtual key expansion is too large" }, - { CERR_CharacterRangeTooLong , "Character range is too large and cannot be expanded" }, - { CERR_NonBMPCharactersNotSupportedInKeySection , "Characters with codepoints over U+FFFF are not supported in the key part of the rule" }, - - { CHINT_UnreachableRule , "This rule will never be matched as another rule takes precedence"}, - { CHINT_NonUnicodeFile , "Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8"}, - { CHINT_IndexStoreLong , "The store referenced in index() is longer than the store referenced in any()"}, - - { CWARN_TooManyWarnings , "Too many warnings or errors"}, - { CWARN_OldVersion , "The keyboard file is an old version"}, - { CWARN_BitmapNotUsed , "The 'bitmaps' statement is obsolete and only the first bitmap referred to will be used, you should use 'bitmap'."}, - { CWARN_CustomLanguagesNotSupported , "Languages over 0x1FF, 0x1F are not supported correctly by Windows. You should use no LANGUAGE line instead."}, - { CWARN_KeyBadLength , "There are too many characters in the keystroke part of the rule."}, - { CWARN_IndexStoreShort , "The store referenced in index() is shorter than the store referenced in any()"}, - { CWARN_UnicodeInANSIGroup , "A Unicode character was found in an ANSI group"}, - { CWARN_ANSIInUnicodeGroup , "An ANSI character was found in a Unicode group"}, - { CWARN_UnicodeSurrogateUsed , "A Unicode surrogate character was found. You should use Unicode scalar values to represent values > U+FFFF"}, - { CWARN_ReservedCharacter , "A Unicode character was found that should not be used"}, - { CWARN_Info , "Information"}, - { CWARN_VirtualKeyWithMnemonicLayout , "Virtual key used instead of virtual character key with a mnemonic layout"}, - { CWARN_VirtualCharKeyWithPositionalLayout , "Virtual character key used with a positional layout instead of mnemonic layout"}, - { CWARN_StoreAlreadyUsedAsOptionOrCall , "Store already used as an option or in a call statement and should not be used as a normal store"}, - { CWARN_StoreAlreadyUsedAsStoreOrCall , "Store already used as a normal store or in a call statement and should not be used as an option"}, - { CWARN_StoreAlreadyUsedAsStoreOrOption , "Store already used as a normal store or as an option and should not be used in a call statement"}, - { CWARN_PunctuationInEthnologueCode , "Punctuation should not be used to separate Ethnologue codes; instead use spaces"}, - { CWARN_PlatformNotInTargets , "The specified platform is not a target platform"}, - { CWARN_HeaderStatementIsDeprecated , "Header statements are deprecated; use instead the equivalent system store"}, - { CWARN_UseNotLastStatementInRule , "A rule with use() statements in the output should not have other content following the use() statements"}, - { CWARN_KVKFileIsInSourceFormat , ".kvk file should be binary but is an XML file"}, - { CWARN_DontMixChiralAndNonChiralModifiers , "Don't mix the use of left/right modifiers with non-left/right modifiers in the same platform"}, - { CWARN_MixingLeftAndRightModifiers , "Left and right modifiers should not both be used in the same rule"}, - { CWARN_LanguageHeadersDeprecatedInKeyman10 , "This language header has been deprecated in Keyman 10. Instead, add language metadata in the package file"}, - { CWARN_HotkeyHasInvalidModifier , "Hotkey has modifiers that are not supported. Use only SHIFT, CTRL and ALT"}, - { CWARN_NulNotFirstStatementInContext , "nul must be the first statement in the context"}, - { CWARN_IfShouldBeAtStartOfContext , "if, platform and baselayout should be at start of context (after nul, if present)"}, - { CWARN_KeyShouldIncludeNCaps , "Other rules which reference this key include CAPS or NCAPS modifiers, so this rule must include NCAPS modifier to avoid inconsistent matches"}, - { CWARN_VirtualKeyInOutput , "Virtual keys are not supported in output"}, - - { 0, nullptr } -}; - -const KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) { - return CompilerErrorMap[code]; -} diff --git a/developer/src/kmcmplib/src/CompMsg.h b/developer/src/kmcmplib/src/CompMsg.h deleted file mode 100644 index e9a15f82fe..0000000000 --- a/developer/src/kmcmplib/src/CompMsg.h +++ /dev/null @@ -1,5 +0,0 @@ - -#include "km_types.h" -#include - -const KMX_CHAR *GetCompilerErrorString(KMX_DWORD code) ; diff --git a/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp b/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp index b889a4fd7e..155b125258 100644 --- a/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp +++ b/developer/src/kmcmplib/src/CompileKeyboardBuffer.cpp @@ -20,13 +20,13 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk) kmcmp::FMnemonicLayout = FALSE; if (!fk) { - AddCompileError(CERR_SomewhereIGotItWrong); + ReportCompilerMessage(KmnCompilerMessages::FATAL_SomewhereIGotItWrong); return FALSE; } str = new KMX_WCHAR[LINESIZE]; if (!str) { - AddCompileError(CERR_CannotAllocateMemory); + ReportCompilerMessage(KmnCompilerMessages::FATAL_CannotAllocateMemory); return FALSE; } @@ -66,39 +66,42 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk) if(kmcmp::FShouldAddCompilerVersion) { u16sprintf(str,LINESIZE, L"Created with Keyman Developer version %d.%d.%d.%d", KEYMAN_VersionMajor, KEYMAN_VersionMinor, KEYMAN_VersionPatch, 0); - AddStore(fk, TSS_KEYMANCOPYRIGHT, str); + if(!AddStore(fk, TSS_KEYMANCOPYRIGHT, str)) { + return FALSE; + } } /* Add a system store for the Keyman edition number */ - AddStore(fk, TSS_CUSTOMKEYMANEDITION, u"0"); - AddStore(fk, TSS_CUSTOMKEYMANEDITIONNAME, u"Keyman"); + if(!AddStore(fk, TSS_CUSTOMKEYMANEDITION, u"0")) { + return FALSE; + } + if(!AddStore(fk, TSS_CUSTOMKEYMANEDITIONNAME, u"Keyman")) { + return FALSE; + } int offset = 0; // must preprocess for group and store names -> this isn't really necessary, but never mind! - while ((msg = ReadLine(infile, sz, offset, str, TRUE)) == CERR_None) + while ((msg = ReadLine(infile, sz, offset, str, TRUE)) == STATUS_Success) { p = str; switch (LineTokenType(&p)) { case T_VERSION: *(p + 4) = 0; - if ((msg = AddStore(fk, TSS_VERSION, p)) != CERR_None) { - AddCompileError(msg); + if (!AddStore(fk, TSS_VERSION, p)) { return FALSE; } break; case T_GROUP: - if ((msg = ProcessGroupLine(fk, p)) != CERR_None) { - AddCompileError(msg); + if (!ProcessGroupLine(fk, p)) { return FALSE; } break; case T_STORE: - if ((msg = ProcessStoreLine(fk, p)) != CERR_None) { - AddCompileError(msg); + if (!ProcessStoreLine(fk, p)) { return FALSE; } break; @@ -108,8 +111,8 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk) } } - if (msg != CERR_EndOfFile) { - AddCompileError(msg); + if (msg != STATUS_EndOfFile) { + ReportCompilerMessage(msg); return FALSE; } @@ -121,32 +124,30 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk) kmcmp::CodeConstants->reindex(); /* ReadLine will automatically skip over $Keyman lines, and parse wrapped lines */ - while ((msg = ReadLine(infile, sz, offset, str, FALSE)) == CERR_None) + while ((msg = ReadLine(infile, sz, offset, str, FALSE)) == STATUS_Success) { - msg = ParseLine(fk, str); - if (msg != CERR_None) { - AddCompileError(msg); + if(!ParseLine(fk, str)) { return FALSE; } } - if (msg != CERR_EndOfFile) { - AddCompileError(msg); + if (msg != STATUS_EndOfFile) { + ReportCompilerMessage(msg); return FALSE; } - ProcessGroupFinish(fk); + if(!ProcessGroupFinish(fk)) { + return FALSE; + } if (kmcmp::FSaveDebug) kmcmp::RecordDeadkeyNames(fk); /* Add the compiler version as a system store */ - if ((msg = kmcmp::AddCompilerVersionStore(fk)) != CERR_None) { - AddCompileError(msg); + if (!kmcmp::AddCompilerVersionStore(fk)) { return FALSE; } - if ((msg = BuildVKDictionary(fk)) != CERR_None) { - AddCompileError(msg); + if (!BuildVKDictionary(fk)) { return FALSE; } diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index be83f55ac5..11c8f4a26f 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -103,32 +103,26 @@ #include "UnreachableRules.h" #include "CheckForDuplicates.h" #include "kmx_u16.h" -#include /* These macros are adapted from winnt.h and legacy use only */ #define MAKELANGID(p, s) ((((uint16_t)(s)) << 10) | (uint16_t)(p)) #define PRIMARYLANGID(lgid) ((uint16_t)(lgid) & 0x3ff) #define SUBLANGID(lgid) ((uint16_t)(lgid) >> 10) -#define COMPILE_ERROR_MAX_LEN (SZMAX_ERRORTEXT + 1 + 280) - using namespace kmcmp; - char ErrExtraLIB[ERR_EXTRA_LIB_LEN]; // utf-8 KMX_BOOL AWarnDeprecatedCode_GLOBAL_LIB; namespace kmcmp{ KMX_BOOL FShouldAddCompilerVersion = TRUE; KMX_BOOL FSaveDebug, FCompilerWarningsAsErrors; // I4865 // I4866 - int ErrChr; - int nErrors = 0; KMX_BOOL FMnemonicLayout = FALSE; KMX_BOOL FOldCharPosMatching = FALSE; int CompileTarget; int BeginLine[4]; KMX_BOOL IsValidCallStore(PFILE_STORE fs); - KMX_BOOL CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall); + void CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall); KMX_DWORD UTF32ToUTF16(int n, int *n1, int *n2); KMX_DWORD CheckUTF16(int n); int cmpkeys(const void *key, const void *elem); @@ -144,7 +138,7 @@ KMX_BOOL IsSameToken(PKMX_WCHAR *p, KMX_WCHAR const * token); KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode); PKMX_WCHAR GetDelimitedString(PKMX_WCHAR *p, KMX_WCHAR const * Delimiters, KMX_WORD Flags); KMX_DWORD GetXString(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_WCHAR const * token, PKMX_WCHAR output, int max, int offset, PKMX_WCHAR *newp, int isVKey, int isUnicode); -KMX_DWORD GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets); +KMX_BOOL GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets); int GetGroupNum(PFILE_KEYBOARD fk, PKMX_WCHAR p); @@ -157,7 +151,7 @@ KMX_DWORD ImportBitmapFile(PFILE_KEYBOARD fk, PKMX_WCHAR szName, PKMX_DWORD File KMX_DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, KMX_DWORD storeIndex); int GetVKCode(PFILE_KEYBOARD fk, PKMX_WCHAR p); // I3438 // TODO: Consolidate GetDeadKey and GetVKCode? -KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp); +KMX_BOOL ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp); KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx); KMX_DWORD process_reset(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx); @@ -239,10 +233,7 @@ enum LinePrefixType { lptNone, lptKeymanAndKeymanWeb, lptKeymanWebOnly, lptKeyma /* Compile target */ -kmcmp_CompilerMessageProc msgproc = NULL; -kmcmp_LoadFileProc loadfileproc = NULL; - -void* msgprocContext = NULL; +kmcmp_LoadFileProc kmcmp::loadfileproc = NULL; int kmcmp::currentLine = 0; @@ -270,52 +261,8 @@ PKMX_STR wstrtostr(PKMX_WCHAR in) return result; } -KMX_BOOL kmcmp::AddCompileWarning(PKMX_CHAR buf) -{ - (*msgproc)(kmcmp::currentLine + 1, CWARN_Info, buf, msgprocContext); - return FALSE; -} -KMX_BOOL AddCompileError(KMX_DWORD msg) -{ - KMX_CHAR szText[COMPILE_ERROR_MAX_LEN]; - const KMX_CHAR* szTextp = NULL; - - if (msg & CERR_FATAL) - { - szTextp = GetCompilerErrorString(msg); - (*msgproc)(kmcmp::currentLine + 1, msg, szTextp, msgprocContext); - kmcmp::nErrors++; - return TRUE; - } - - if (msg & CERR_ERROR) - kmcmp::nErrors++; - szTextp = GetCompilerErrorString(msg); - - if (szTextp) { - strcpy(szText, szTextp); - } else { - snprintf(szText, COMPILE_ERROR_MAX_LEN, "Unknown error %x", msg); - } - - if (kmcmp::ErrChr > 0) { - char *szTextNull = strchr(szText, 0); - snprintf(szTextNull, COMPILE_ERROR_MAX_LEN-(szTextNull-szText), " character offset: %d", kmcmp::ErrChr); - } - - if (*ErrExtraLIB) { - char *szTextNull = strchr(szText, 0); - snprintf(szTextNull, COMPILE_ERROR_MAX_LEN-(szTextNull-szText), "%s", ErrExtraLIB); - } - - ErrChr = 0; *ErrExtraLIB =0; - if (!(*msgproc)(kmcmp::currentLine, msg, szText, msgprocContext)) return TRUE; - return FALSE; -} - -KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) -{ +KMX_BOOL ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) { KMX_WCHAR tstr[128]; PKMX_WCHAR q, pp; int BeginMode; @@ -323,30 +270,42 @@ KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) pp = p; - q = ( PKMX_WCHAR) u16chr(p, '>'); - if (!q) return CERR_NoTokensFound; + q = (PKMX_WCHAR) u16chr(p, '>'); + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_NoTokensFound); + return FALSE; + } while (iswspace(*p)) p++; if (u16nicmp(p, u"unicode", 7) == 0) BeginMode = BEGIN_UNICODE; else if (u16nicmp(p, u"ansi", 4) == 0) BeginMode = BEGIN_ANSI; else if (u16nicmp(p, u"newContext", 10) == 0) BeginMode = BEGIN_NEWCONTEXT; else if (u16nicmp(p, u"postKeystroke", 13) == 0) BeginMode = BEGIN_POSTKEYSTROKE; - else if (*p != '>') return CERR_InvalidToken; + else if (*p != '>') { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidToken); + return FALSE; + } else BeginMode = BEGIN_ANSI; if(kmcmp::BeginLine[BeginMode] != -1) { - return CERR_RepeatedBegin; + ReportCompilerMessage(KmnCompilerMessages::ERROR_RepeatedBegin); + return FALSE; } kmcmp::BeginLine[BeginMode] = kmcmp::currentLine; - if ((msg = GetRHS(fk, p, tstr, 80, (int)(p - pp), FALSE)) != CERR_None) return msg; + if ((msg = GetRHS(fk, p, tstr, 80, (int)(p - pp), FALSE)) != STATUS_Success) { + ReportCompilerMessage(msg); + return FALSE; + } if (tstr[0] != UC_SENTINEL || tstr[1] != CODE_USE) { - return CERR_InvalidBegin; + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidBegin); + return FALSE; } if (tstr[3] != 0) { - return CERR_InvalidToken; + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidToken); + return FALSE; } if (BeginMode == BEGIN_ANSI || BeginMode == BEGIN_UNICODE) { @@ -359,20 +318,18 @@ KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) /* Record a system store for the line number of the begin statement */ AddDebugStore(fk, BeginMode == BEGIN_UNICODE ? DEBUGSTORE_BEGIN u"Unicode" : DEBUGSTORE_BEGIN u"ANSI"); } - } - else { - PFILE_GROUP gp = &fk->dpGroupArray[tstr[2] - 1]; - if (!gp->fReadOnly) { - return BeginMode == BEGIN_NEWCONTEXT ? - CERR_NewContextGroupMustBeReadonly : - CERR_PostKeystrokeGroupMustBeReadonly; - } - return AddStore(fk, BeginMode == BEGIN_NEWCONTEXT ? TSS_BEGIN_NEWCONTEXT : TSS_BEGIN_POSTKEYSTROKE, tstr, NULL); + } else { + PFILE_GROUP gp = &fk->dpGroupArray[tstr[2] - 1]; + if (!gp->fReadOnly) { + ReportCompilerMessage(BeginMode == BEGIN_NEWCONTEXT ? + KmnCompilerMessages::ERROR_NewContextGroupMustBeReadonly : + KmnCompilerMessages::ERROR_PostKeystrokeGroupMustBeReadonly); + return FALSE; } + return AddStore(fk, BeginMode == BEGIN_NEWCONTEXT ? TSS_BEGIN_NEWCONTEXT : TSS_BEGIN_POSTKEYSTROKE, tstr, NULL); + } - - - return CERR_None; + return TRUE; } KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p) { @@ -382,16 +339,15 @@ KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p) { case CODE_CONTEXT: case CODE_CONTEXTEX: case CODE_INDEX: - return CERR_ContextAndIndexInvalidInMatchNomatch; + return KmnCompilerMessages::ERROR_ContextAndIndexInvalidInMatchNomatch; } } p = incxstr(p); } - return CERR_None; + return STATUS_Success; } -KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) -{ +KMX_BOOL ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) { PKMX_WCHAR p, q, pp; PFILE_GROUP gp; KMX_DWORD msg; @@ -413,49 +369,72 @@ KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) case T_BEGIN: // after a begin can be "Unicode" or "ANSI" or nothing (=ANSI) - if ((msg = ProcessBeginLine(fk, p)) != CERR_None) return msg; + if (!ProcessBeginLine(fk, p)) { + return FALSE; + } 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? + if (fk->currentGroup == 0xFFFFFFFF) { + fk->currentGroup = 0; + } else { + if (!ProcessGroupFinish(fk)) { + return FALSE; // finish off previous group first? + } fk->currentGroup++; } - // if( (err = ProcessGroupLine( fk, p )) != CERR_None ) return err; break; case T_NAME: kmcmp::WarnDeprecatedHeader(); // I4866 q = GetDelimitedString(&p, u"\"\"", 0); - if (!q) return CERR_InvalidName; + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidName); + return FALSE; + } - if ((msg = AddStore(fk, TSS_NAME, q)) != CERR_None) return msg; + if (!AddStore(fk, TSS_NAME, q)) { + return FALSE; + } break; case T_COPYRIGHT: kmcmp::WarnDeprecatedHeader(); // I4866 q = GetDelimitedString(&p, u"\"\"", 0); - if (!q) return CERR_InvalidCopyright; + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidCopyright); + return FALSE; + } - if ((msg = AddStore(fk, TSS_COPYRIGHT, q)) != CERR_None) return msg; + if (!AddStore(fk, TSS_COPYRIGHT, q)) { + return FALSE; + } break; case T_MESSAGE: kmcmp::WarnDeprecatedHeader(); // I4866 q = GetDelimitedString(&p, u"\"\"", 0); - if (!q) return CERR_InvalidMessage; + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidMessage); + return FALSE; + } - if ((msg = AddStore(fk, TSS_MESSAGE, q)) != CERR_None) return msg; + if (!AddStore(fk, TSS_MESSAGE, q)) { + return FALSE; + } break; case T_LANGUAGENAME: kmcmp::WarnDeprecatedHeader(); // I4866 q = GetDelimitedString(&p, u"\"\"", 0); - if (!q) return CERR_InvalidLanguageName; + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLanguageName); + return FALSE; + } - if ((msg = AddStore(fk, TSS_LANGUAGENAME, q)) != CERR_None) return msg; + if (!AddStore(fk, TSS_LANGUAGENAME, q)) { + return FALSE; + } break; case T_LANGUAGE: @@ -464,7 +443,9 @@ KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) KMX_WCHAR *tokcontext = NULL; q = u16tok(p, p_sep, &tokcontext); // I3481 - if ((msg = AddStore(fk, TSS_LANGUAGE, q)) != CERR_None) return msg; + if (!AddStore(fk, TSS_LANGUAGE, q)) { + return FALSE; + } break; } case T_LAYOUT: @@ -472,79 +453,118 @@ KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) kmcmp::WarnDeprecatedHeader(); // I4866 KMX_WCHAR *tokcontext = NULL; q = u16tok(p, p_sep, &tokcontext); // I3481 - if ((msg = AddStore(fk, TSS_LAYOUT, q)) != CERR_None) return msg; + if (!AddStore(fk, TSS_LAYOUT, q)) { + return FALSE; + } break; } case T_CAPSOFF: kmcmp::WarnDeprecatedHeader(); // I4866 - if ((msg = AddStore(fk, TSS_CAPSALWAYSOFF, u"1")) != CERR_None) return msg; + if (!AddStore(fk, TSS_CAPSALWAYSOFF, u"1")) { + return FALSE; + } break; case T_CAPSON: kmcmp::WarnDeprecatedHeader(); // I4866 - if ((msg = AddStore(fk, TSS_CAPSONONLY, u"1")) != CERR_None) return msg; + if (!AddStore(fk, TSS_CAPSONONLY, u"1")) { + return FALSE; + } break; case T_SHIFT: kmcmp::WarnDeprecatedHeader(); // I4866 - if ((msg = AddStore(fk, TSS_SHIFTFREESCAPS, u"1")) != CERR_None) return msg; + if (!AddStore(fk, TSS_SHIFTFREESCAPS, u"1")) { + return FALSE; + } break; case T_HOTKEY: { kmcmp::WarnDeprecatedHeader(); // I4866 KMX_WCHAR *tokcontext = NULL; - if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) return CERR_CodeInvalidInThisSection; // I3481 - if ((msg = AddStore(fk, TSS_HOTKEY, q)) != CERR_None) return msg; + if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_CodeInvalidInThisSection); // I3481 + return FALSE; + } + if (!AddStore(fk, TSS_HOTKEY, q)) { + return FALSE; + } break; } case T_BITMAP: { kmcmp::WarnDeprecatedHeader(); // I4866 KMX_WCHAR *tokcontext = NULL; - if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidBitmapLine); // I3481 + return FALSE; + } while (iswspace(*q)) q++; if (*q == '"') { p = q; q = GetDelimitedString(&p, u"\"\"", 0); - if (!q) return CERR_InvalidBitmapLine; + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidBitmapLine); + return FALSE; + } } - if ((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; + if (!AddStore(fk, TSS_BITMAP, q)) { + return FALSE; + } break; } case T_BITMAPS: { kmcmp::WarnDeprecatedHeader(); // I4866 KMX_WCHAR *tokcontext = NULL; - AddWarning(CWARN_BitmapNotUsed); + ReportCompilerMessage(KmnCompilerMessages::WARN_BitmapNotUsed); - if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) return CERR_InvalidBitmapLine; // I3481 + if ((q = u16tok(p, p_sep, &tokcontext)) == NULL) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidBitmapLine); // I3481 + return FALSE; + } - if ((PKMX_WCHAR) u16chr(q, ',')) *(PKMX_WCHAR) u16chr(q, ',') = 0; - if ((msg = AddStore(fk, TSS_BITMAP, q)) != CERR_None) return msg; + if ((PKMX_WCHAR) u16chr(q, ',')) { + *(PKMX_WCHAR) u16chr(q, ',') = 0; + } + if (!AddStore(fk, TSS_BITMAP, q)) { + return FALSE; + } break; } case T_KEYTOKEY: // A rule - if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; - if ((msg = ProcessKeyLine(fk, p, IsUnicode)) != CERR_None) return msg; + if (fk->currentGroup == 0xFFFFFFFF) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_CodeInvalidInThisSection); + return FALSE; + } + if ((msg = ProcessKeyLine(fk, p, IsUnicode)) != STATUS_Success) { + ReportCompilerMessage(msg); + return FALSE; + } break; case T_MATCH: - if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + if (fk->currentGroup == 0xFFFFFFFF) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_CodeInvalidInThisSection); + return FALSE; + } { PKMX_WCHAR buf = new KMX_WCHAR[GLOBAL_BUFSIZE]; - if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE - 1, (int)(p - pp), IsUnicode)) != CERR_None) + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE - 1, (int)(p - pp), IsUnicode)) != STATUS_Success) { delete[] buf; - return msg; + ReportCompilerMessage(msg); + return FALSE; } - if ((msg = ValidateMatchNomatchOutput(buf)) != CERR_None) { + if ((msg = ValidateMatchNomatchOutput(buf)) != STATUS_Success) { delete[] buf; - return msg; + ReportCompilerMessage(msg); + return FALSE; } gp = &fk->dpGroupArray[fk->currentGroup]; @@ -569,18 +589,23 @@ KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) break; case T_NOMATCH: - if (fk->currentGroup == 0xFFFFFFFF) return CERR_CodeInvalidInThisSection; + if (fk->currentGroup == 0xFFFFFFFF) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_CodeInvalidInThisSection); + return FALSE; + } { PKMX_WCHAR buf = new KMX_WCHAR[GLOBAL_BUFSIZE]; - if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE, (int)(p - pp), IsUnicode)) != CERR_None) + if ((msg = GetRHS(fk, p, buf, GLOBAL_BUFSIZE, (int)(p - pp), IsUnicode)) != STATUS_Success) { delete[] buf; - return msg; + ReportCompilerMessage(msg); + return FALSE; } - if ((msg = ValidateMatchNomatchOutput(buf)) != CERR_None) { + if ((msg = ValidateMatchNomatchOutput(buf)) != STATUS_Success) { delete[] buf; - return msg; + ReportCompilerMessage(msg); + return FALSE; } gp = &fk->dpGroupArray[fk->currentGroup]; @@ -602,21 +627,25 @@ KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) break; default: - return CERR_InvalidToken; + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidToken); + return FALSE; } - return CERR_None; + return TRUE; } //********************************************************************************************************************** -KMX_DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +KMX_BOOL ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) { PFILE_GROUP gp; PKMX_WCHAR q; gp = new FILE_GROUP[fk->cxGroupArray + 1]; - if (!gp) return CERR_CannotAllocateMemory; + if (!gp) { + ReportCompilerMessage(KmnCompilerMessages::FATAL_CannotAllocateMemory); + return FALSE; + } if (fk->dpGroupArray) { @@ -634,7 +663,10 @@ KMX_DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) gp->cxKeyArray = 0; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q) return CERR_InvalidGroupLine; + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidGroupLine); + return FALSE; + } gp->fUsingKeys = FALSE; gp->fReadOnly = IsSameToken(&p, u"readonly"); @@ -697,49 +729,61 @@ int kmcmp::cmpkeys(const void *key, const void *elem) return(char_key - char_elem); // akey->Key - aelem->Key); } -KMX_DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) -{ +KMX_BOOL ProcessGroupFinish(PFILE_KEYBOARD fk) { PFILE_GROUP gp; KMX_DWORD msg; - if (fk->currentGroup == 0xFFFFFFFF) return CERR_None; - // Just got to first group - so nothing to finish yet + if (fk->currentGroup == 0xFFFFFFFF) { + // Just got to first group - so nothing to finish yet + return TRUE; + } gp = &fk->dpGroupArray[fk->currentGroup]; // Finish off the previous group stuff! - if ((msg = ExpandCapsRulesForGroup(fk, gp)) != CERR_None) return msg; + if ((msg = ExpandCapsRulesForGroup(fk, gp)) != STATUS_Success) { + ReportCompilerMessage(msg); + return FALSE; + } qsort(gp->dpKeyArray, gp->cxKeyArray, sizeof(FILE_KEY), kmcmp::cmpkeys); - return VerifyUnreachableRules(gp); + VerifyUnreachableRules(gp); + + return TRUE; } /*************************************** * Store management */ -KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) -{ +KMX_BOOL ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) { PKMX_WCHAR q, pp; PFILE_STORE sp; - //WCHAR temp[GLOBAL_BUFSIZE]; KMX_DWORD msg; int i = 0; pp = p; - if ((q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL)) == NULL) return CERR_InvalidStoreLine; + if ((q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL)) == NULL) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidStoreLine); + return FALSE; + } - if (*q == *SSN__PREFIX) - { - for (i = 0; StoreTokens[i]; i++) - if (!u16icmp(q, StoreTokens[i])) // I3481 + if (*q == *SSN__PREFIX) { + for (i = 0; StoreTokens[i]; i++) { + if (!u16icmp(q, StoreTokens[i])) { // I3481 break; - if (!StoreTokens[i]) return CERR_InvalidSystemStore; + } + } + if (!StoreTokens[i]) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidSystemStore); + return FALSE; + } } if(!resizeStoreArray(fk)) { - return CERR_CannotAllocateMemory; + ReportCompilerMessage(KmnCompilerMessages::FATAL_CannotAllocateMemory); + return FALSE; } sp = &fk->dpStoreArray[fk->cxStoreArray]; @@ -754,10 +798,10 @@ KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) { PKMX_WCHAR temp = new KMX_WCHAR[GLOBAL_BUFSIZE]; - if ((msg = GetXString(fk, p, u"c\n", temp, GLOBAL_BUFSIZE - 1, (int)(p - pp), &p, FALSE, TRUE)) != CERR_None) - { + if ((msg = GetXString(fk, p, u"c\n", temp, GLOBAL_BUFSIZE - 1, (int)(p - pp), &p, FALSE, TRUE)) != STATUS_Success) { delete[] temp; - return msg; + ReportCompilerMessage(msg); + return FALSE; } sp->dwSystemID = i; @@ -768,23 +812,29 @@ KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) } if (xstrlen(sp->dpString) == 1 && *sp->dpString != UC_SENTINEL && - sp->dwSystemID == 0 && (fk->version >= VERSION_60 || fk->version == 0)) - { + 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); + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_60FeatureOnly_NamedCodes); + return FALSE; + } // Add a single char store as a defined character constant - if (Uni_IsSurrogate1(*sp->dpString)) + if (Uni_IsSurrogate1(*sp->dpString)) { kmcmp::CodeConstants->AddCode(Uni_SurrogateToUTF32(sp->dpString[0], sp->dpString[1]), sp->szName, fk->cxStoreArray); - else + } else { kmcmp::CodeConstants->AddCode(sp->dpString[0], sp->szName, fk->cxStoreArray); + } kmcmp::CodeConstants->reindex(); // has to be done after every character add due to possible use in another store. // I4982 } fk->cxStoreArray++; // increment now, because GetXString refers to stores - if (i > 0) - if ((msg = ProcessSystemStore(fk, i, sp)) != CERR_None) return msg; + if (i > 0) { + if (!ProcessSystemStore(fk, i, sp)) { + return FALSE; + } + } return CheckForDuplicateStore(fk, sp); } @@ -824,11 +874,11 @@ bool resizeKeyArray(PFILE_GROUP gp, int increment) { return true; } -KMX_DWORD AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, KMX_DWORD *dwStoreID) -{ +KMX_BOOL AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, KMX_DWORD *dwStoreID) { PFILE_STORE sp; if(!resizeStoreArray(fk)) { - return CERR_CannotAllocateMemory; + ReportCompilerMessage(KmnCompilerMessages::FATAL_CannotAllocateMemory); + return FALSE; } sp = &fk->dpStoreArray[fk->cxStoreArray]; @@ -851,7 +901,7 @@ KMX_DWORD AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, fk->cxStoreArray++; - return ProcessSystemStore( fk, SystemID, sp); + return ProcessSystemStore(fk, SystemID, sp); } KMX_DWORD AddDebugStore(PFILE_KEYBOARD fk, KMX_WCHAR const * str) @@ -861,7 +911,7 @@ KMX_DWORD AddDebugStore(PFILE_KEYBOARD fk, KMX_WCHAR const * str) u16sprintf(tstr, _countof(tstr), L"%d", kmcmp::currentLine); // I3481 if(!resizeStoreArray(fk)) { - return CERR_CannotAllocateMemory; + return KmnCompilerMessages::FATAL_CannotAllocateMemory; } sp = &fk->dpStoreArray[fk->cxStoreArray]; @@ -878,13 +928,12 @@ KMX_DWORD AddDebugStore(PFILE_KEYBOARD fk, KMX_WCHAR const * str) sp->dwSystemID = TSS_DEBUG_LINE; fk->cxStoreArray++; - return CERR_None; + return STATUS_Success; } PKMX_WCHAR pssBuf = NULL; -KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp) -{ +KMX_BOOL ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp) { //WCHAR buf[GLOBAL_BUFSIZE]; int i, j; KMX_DWORD msg; @@ -895,9 +944,14 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE switch (SystemID) { + case TSS_BASELAYOUT: + break; + case TSS_BITMAP: - if ((msg = ImportBitmapFile(fk, sp->dpString, &fk->dwBitmapSize, &fk->lpBitmap)) != CERR_None) - return msg; + if ((msg = ImportBitmapFile(fk, sp->dpString, &fk->dwBitmapSize, &fk->lpBitmap)) != STATUS_Success) { + ReportCompilerMessage(msg); + return FALSE; + } break; case TSS_CALLDEFINITION: @@ -920,16 +974,31 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE case TSS_COPYRIGHT: break; + case TSS_CUSTOMKEYMANEDITION: + break; + + case TSS_CUSTOMKEYMANEDITIONNAME: + break; + case TSS_DEBUG_LINE: break; case TSS_ETHNOLOGUECODE: - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_EthnologueCode); - if ((msg = ProcessEthnologueStore(sp->dpString)) != CERR_None) return msg; // I2646 + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_60FeatureOnly_EthnologueCode); + return FALSE; + } + if ((msg = ProcessEthnologueStore(sp->dpString)) != STATUS_Success) { + ReportCompilerMessage(msg); + return FALSE; // I2646 + } break; case TSS_HOTKEY: - if ((msg = ProcessHotKey(sp->dpString, &fk->dwHotKey)) != CERR_None) return msg; + if ((msg = ProcessHotKey(sp->dpString, &fk->dwHotKey)) != STATUS_Success) { + ReportCompilerMessage(msg); + return FALSE; + } u16sprintf(buf, GLOBAL_BUFSIZE, L"%d", (int)fk->dwHotKey); // I3481 delete[] sp->dpString; sp->dpString = new KMX_WCHAR[u16len(buf) + 1]; @@ -937,20 +1006,30 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE break; case TSS_INCLUDECODES: - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_60FeatureOnly_NamedCodes); + return FALSE; + } if (!kmcmp::CodeConstants->LoadFile(fk, sp->dpString)) { - return CERR_CannotLoadIncludeFile; + ReportCompilerMessage(KmnCompilerMessages::ERROR_CannotLoadIncludeFile); + return FALSE; } kmcmp::CodeConstants->reindex(); // I4982 break; + case TSS_KEYMANCOPYRIGHT: + break; + case TSS_LANGUAGE: { KMX_WCHAR *context = NULL; KMX_WCHAR sep_c[3] = u", "; PKMX_WCHAR p_sep_c = sep_c; q = u16tok(sp->dpString, p_sep_c, &context); // I3481 - if (!q) return CERR_InvalidLanguageLine; + if (!q) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLanguageLine); + return FALSE; + } i = xatoi(&q); KMX_WCHAR sep_n[4] = u" c\n"; @@ -958,15 +1037,23 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE q = u16tok(NULL, p_sep_n, &context); // I3481 if (!q) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_InvalidLanguageLine); + if(!VerifyKeyboardVersion(fk, VERSION_70)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLanguageLine); + return FALSE; + } 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); + if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLanguageLine); + return FALSE; + } + if (i >= 0x200 || j >= 0x20) { + ReportCompilerMessage(KmnCompilerMessages::WARN_CustomLanguagesNotSupported); + } fk->KeyboardID = (KMX_DWORD)MAKELANGID(i, j); @@ -980,8 +1067,14 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE case TSS_LANGUAGENAME: break; + case TSS_LAYER: + break; + case TSS_LAYOUT: - if (fk->KeyboardID == 0) return CERR_LayoutButNoLanguage; + if (fk->KeyboardID == 0) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_LayoutButNoLanguage); + return FALSE; + } q = sp->dpString; @@ -992,12 +1085,16 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE break; case TSS_MNEMONIC: - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_MnemonicLayout); + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_60FeatureOnly_MnemonicLayout); + return FALSE; + }; kmcmp::FMnemonicLayout = atoiW(sp->dpString) == 1; if (kmcmp::FMnemonicLayout && FindSystemStore(fk, TSS_CASEDKEYS) != NULL) { // The &CasedKeys system store is not supported for // mnemonic layouts - return CERR_CasedKeysNotSupportedWithMnemonicLayout; + ReportCompilerMessage(KmnCompilerMessages::ERROR_CasedKeysNotSupportedWithMnemonicLayout); + return FALSE; } break; @@ -1005,19 +1102,31 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE break; case TSS_OLDCHARPOSMATCHING: - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_OldCharPosMatching); + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_60FeatureOnly_OldCharPosMatching); + return FALSE; + } kmcmp::FOldCharPosMatching = atoiW(sp->dpString); break; + case TSS_PLATFORM: + case TSS_PLATFORM_MATCH: + case TSS_PLATFORM_NOMATCH: + // Never matched but included for completeness + break; + case TSS_SHIFTFREESCAPS: if (*sp->dpString == u'1') fk->dwFlags |= KF_SHIFTFREESCAPS; break; case TSS_VERSION: - if ((fk->dwFlags & KF_AUTOMATICVERSION) == 0) return CERR_VersionAlreadyIncluded; + if ((fk->dwFlags & KF_AUTOMATICVERSION) == 0) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_VersionAlreadyIncluded); + return FALSE; + } p = sp->dpString; if (u16tof (p) < 5.0) { - AddWarning(CWARN_OldVersion); + ReportCompilerMessage(KmnCompilerMessages::WARN_OldVersion); } if (u16ncmp(p, u"3.0", 3) == 0) fk->version = VERSION_50; //0x0a0b000n= a.bn @@ -1036,7 +1145,10 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE else if (u16ncmp(p, u"16.0", 4) == 0) fk->version = VERSION_160; // KMXPlus else if (u16ncmp(p, u"17.0", 4) == 0) fk->version = VERSION_170; // Flicks and gestures - else return CERR_InvalidVersion; + else { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidVersion); + return FALSE; + } if (fk->version < VERSION_60) kmcmp::FOldCharPosMatching = TRUE; @@ -1045,7 +1157,10 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE break; case TSS_VISUALKEYBOARD: - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + if(!VerifyKeyboardVersion(fk, VERSION_70)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_70FeatureOnly); + return FALSE; + } { // Store extra metadata for callers as we mutate this store during // compilation @@ -1075,29 +1190,44 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE break; case TSS_KMW_RTL: case TSS_KMW_HELPTEXT: - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + if(!VerifyKeyboardVersion(fk, VERSION_70)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_70FeatureOnly); + return FALSE; + } break; case TSS_KMW_HELPFILE: case TSS_KMW_EMBEDJS: - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + if(!VerifyKeyboardVersion(fk, VERSION_70)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_70FeatureOnly); + return FALSE; + } break; case TSS_KMW_EMBEDCSS: - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyEmbedCSS); + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_90FeatureOnlyEmbedCSS); + return FALSE; + } break; case TSS_TARGETS: // I4504 - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyTargets); - if((msg = GetCompileTargetsFromTargetsStore(sp->dpString, fk->extra->targets)) != CERR_None) { - return msg; + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_90FeatureOnlyTargets); + return FALSE; + } + if(!GetCompileTargetsFromTargetsStore(sp->dpString, fk->extra->targets)) { + return FALSE; } break; case TSS_WINDOWSLANGUAGES: { + if(!VerifyKeyboardVersion(fk, VERSION_70)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_70FeatureOnly); + return FALSE; + } KMX_WCHAR *context = NULL; - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); size_t szQ = u16len(sp->dpString) * 6 + 1; // I3481 q = new KMX_WCHAR[szQ]; // guaranteed to be enough space for recoding *q = 0; KMX_WCHAR *r = q; @@ -1113,7 +1243,8 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE if (i < 1 || j < 1 || i > 0x3FF || j > 0x3F) { delete[] q; - return CERR_InvalidLanguageLine; + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLanguageLine); + return FALSE; } u16sprintf(r, szQ - (size_t)(r - q), L"x%04.4x ", n); // I3481 @@ -1128,28 +1259,42 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE break; } case TSS_COMPARISON: - VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + if(!VerifyKeyboardVersion(fk, VERSION_80)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_80FeatureOnly); + return FALSE; + } break; case TSS_VKDICTIONARY: // I3438 - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyVirtualKeyDictionary); + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_90FeatureOnlyVirtualKeyDictionary); + return FALSE; + } break; case TSS_LAYOUTFILE: // I3483 - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyLayoutFile); // I4140 + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_90FeatureOnlyLayoutFile); + return FALSE; + } // Used by KMW compiler break; case TSS_KEYBOARDVERSION: // I4140 - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnlyKeyboardVersion); + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_90FeatureOnlyKeyboardVersion); + return FALSE; + } if (!IsValidKeyboardVersion(sp->dpString)) { - return CERR_KeyboardVersionFormatInvalid; + ReportCompilerMessage(KmnCompilerMessages::ERROR_KeyboardVersionFormatInvalid); + return FALSE; } break; case TSS_CASEDKEYS: - if ((msg = VerifyCasedKeys(sp)) != CERR_None) { - return msg; + if ((msg = VerifyCasedKeys(sp)) != STATUS_Success) { + ReportCompilerMessage(msg); + return FALSE; } break; @@ -1169,12 +1314,13 @@ KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE break; default: - return CERR_InvalidSystemStore; + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidSystemStore); + return FALSE; } - return CERR_None; + return TRUE; } -KMX_DWORD GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets) { +KMX_BOOL GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets) { // Compile to .kmx const std::vector KMXKeymanTargets{ u"windows", u"macosx", u"linux", u"desktop" @@ -1214,10 +1360,12 @@ KMX_DWORD GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets } if(!found) { - snprintf(ErrExtraLIB, ERR_EXTRA_LIB_LEN, " target: %s", string_from_u16string(token).c_str()); + ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidTarget, { + /*target*/ string_from_u16string(token).c_str() + }); delete[] p; targets = 0; - return CERR_InvalidTarget; + return FALSE; } } token = u16tok(nullptr, u" ", &ctx); @@ -1225,10 +1373,11 @@ KMX_DWORD GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets delete[] p; if(targets == 0) { - return CERR_NoTargetsSpecified; + ReportCompilerMessage(KmnCompilerMessages::ERROR_NoTargetsSpecified); + return FALSE; } - return CERR_None; + return TRUE; } KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString) { // I4140 @@ -1257,17 +1406,16 @@ KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString) { // I4140 } -KMX_DWORD kmcmp::AddCompilerVersionStore(PFILE_KEYBOARD fk) -{ - KMX_DWORD msg; - +KMX_BOOL kmcmp::AddCompilerVersionStore(PFILE_KEYBOARD fk) { if(!kmcmp::FShouldAddCompilerVersion) { - return CERR_None; + return TRUE; } - if ((msg = AddStore(fk, TSS_COMPILEDVERSION, KEYMAN_VersionWin_W16)) != CERR_None) return msg; + if (!AddStore(fk, TSS_COMPILEDVERSION, KEYMAN_VersionWin_W16)) { + return FALSE; + } - return CERR_None; + return TRUE; } /**************************** @@ -1287,16 +1435,16 @@ KMX_DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PKMX_WCHAR co if (*q == 0) { if (!gp->fUsingKeys) // no key in the rule, so offset is past end of context - return CERR_IndexDoesNotPointToAny; + return KmnCompilerMessages::ERROR_IndexDoesNotPointToAny; if (i < contextOffset) // I4914 // offset is beyond the key - return CERR_IndexDoesNotPointToAny; + return KmnCompilerMessages::ERROR_IndexDoesNotPointToAny; q = key; } // find the any if (*q != UC_SENTINEL || *(q + 1) != CODE_ANY) - return CERR_IndexDoesNotPointToAny; + return KmnCompilerMessages::ERROR_IndexDoesNotPointToAny; int anyStore = *(q + 2) - 1; @@ -1304,27 +1452,29 @@ KMX_DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PKMX_WCHAR co const int indexLength = xstrlen(fk->dpStoreArray[indexStore].dpString); if (indexLength < anyLength) { - AddWarning(CWARN_IndexStoreShort); + ReportCompilerMessage(KmnCompilerMessages::WARN_IndexStoreShort); } else if(indexLength > anyLength) { - AddWarning(CHINT_IndexStoreLong); + ReportCompilerMessage(KmnCompilerMessages::HINT_IndexStoreLong); } } else if (*(p + 1) == CODE_CONTEXTEX) { int contextOffset = *(p + 2); if (contextOffset > xstrlen(context)) - return CERR_ContextExHasInvalidOffset; + return KmnCompilerMessages::ERROR_ContextExHasInvalidOffset; // Due to a limitation in earlier versions of KeymanWeb, the minimum version // for context() referring to notany() is 14.0. See #917 for details. if (kmcmp::CompileTarget == CKF_KEYMANWEB) { for (q = context, i = 1; *q && i < contextOffset; q = incxstr(q), i++); if (*q == UC_SENTINEL && *(q + 1) == CODE_NOTANY) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_140, CERR_140FeatureOnlyContextAndNotAnyWeb); + if(!VerifyKeyboardVersion(fk, VERSION_140)) { + return KmnCompilerMessages::ERROR_140FeatureOnlyContextAndNotAnyWeb; + } } } } } } - return CERR_None; + return STATUS_Success; } /** @@ -1334,24 +1484,24 @@ KMX_DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PKMX_WCHAR co * Test that nul is first, then if(), baselayout(), platform() statements are before any other content. * Also verifies that virtual keys are not found in the context. */ -KMX_BOOL CheckContextStatementPositions(PKMX_WCHAR context) { +void CheckContextStatementPositions(PKMX_WCHAR context) { KMX_BOOL hadContextChar = FALSE; for (PKMX_WCHAR p = context; *p; p = incxstr(p)) { if (*p == UC_SENTINEL) { switch (*(p + 1)) { case CODE_NUL: if (p > context) { - AddWarningBool(CWARN_NulNotFirstStatementInContext); + ReportCompilerMessage(KmnCompilerMessages::WARN_NulNotFirstStatementInContext); } break; case CODE_IFOPT: case CODE_IFSYSTEMSTORE: if (hadContextChar) { - AddWarningBool(CWARN_IfShouldBeAtStartOfContext); + ReportCompilerMessage(KmnCompilerMessages::WARN_IfShouldBeAtStartOfContext); } break; case CODE_EXTENDED: - AddCompileError(CERR_VirtualKeyInContext); + ReportCompilerMessage(KmnCompilerMessages::ERROR_VirtualKeyInContext); break; default: hadContextChar = TRUE; @@ -1361,8 +1511,6 @@ KMX_BOOL CheckContextStatementPositions(PKMX_WCHAR context) { hadContextChar = TRUE; } } - - return TRUE; } /** @@ -1375,11 +1523,11 @@ KMX_DWORD CheckUseStatementsInOutput(PKMX_WCHAR output) { if (*p == UC_SENTINEL && *(p + 1) == CODE_USE) { hasUse = TRUE; } else if (hasUse) { - AddWarning(CWARN_UseNotLastStatementInRule); + ReportCompilerMessage(KmnCompilerMessages::WARN_UseNotLastStatementInRule); break; } } - return CERR_None; + return STATUS_Success; } /** @@ -1391,11 +1539,11 @@ KMX_DWORD CheckVirtualKeysInOutput(PKMX_WCHAR output) { PKMX_WCHAR p; for (p = output; *p; p = incxstr(p)) { if (*p == UC_SENTINEL && *(p + 1) == CODE_EXTENDED) { - AddWarning(CWARN_VirtualKeyInOutput); + ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualKeyInOutput); break; } } - return CERR_None; + return STATUS_Success; } /** @@ -1404,13 +1552,13 @@ KMX_DWORD CheckVirtualKeysInOutput(PKMX_WCHAR output) { KMX_DWORD InjectContextToReadonlyOutput(PKMX_WCHAR pklOut) { if (pklOut[0] != UC_SENTINEL || pklOut[1] != CODE_CONTEXT) { if (u16len(pklOut) > GLOBAL_BUFSIZE - 3) { - return CERR_CannotAllocateMemory; + return KmnCompilerMessages::FATAL_CannotAllocateMemory; } memmove(pklOut + 2, pklOut, (u16len(pklOut) + 1) * 2); pklOut[0] = UC_SENTINEL; pklOut[1] = CODE_CONTEXT; } - return CERR_None; + return STATUS_Success; } /** @@ -1421,7 +1569,7 @@ KMX_DWORD CheckOutputIsReadonly(const PFILE_KEYBOARD fk, const PKMX_WCHAR output PKMX_WCHAR p; for (p = output; *p; p = incxstr(p)) { if (*p != UC_SENTINEL) { - return CERR_OutputInReadonlyGroup; + return KmnCompilerMessages::ERROR_OutputInReadonlyGroup; } switch (*(p + 1)) { case CODE_CALL: @@ -1434,7 +1582,7 @@ KMX_DWORD CheckOutputIsReadonly(const PFILE_KEYBOARD fk, const PKMX_WCHAR output { PFILE_GROUP targetGroup = &fk->dpGroupArray[*(p + 2) - 1]; if (!targetGroup->fReadOnly) { - return CERR_CannotUseReadWriteGroupFromReadonlyGroup; + return KmnCompilerMessages::ERROR_CannotUseReadWriteGroupFromReadonlyGroup; } } continue; @@ -1453,15 +1601,15 @@ KMX_DWORD CheckOutputIsReadonly(const PFILE_KEYBOARD fk, const PKMX_WCHAR output if (p == output) { continue; } - return CERR_OutputInReadonlyGroup; + return KmnCompilerMessages::ERROR_OutputInReadonlyGroup; default: // Note: conceptually, CODE_NUL could be transformed to CODE_CONTEXT // if the context was also empty, but it is probably safest to avoid this, // given CODE_CONTEXT does what we need anyway - return CERR_StatementNotPermittedInReadonlyGroup; + return KmnCompilerMessages::ERROR_StatementNotPermittedInReadonlyGroup; } } - return CERR_None; + return STATUS_Success; } KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode, PKMX_WCHAR pklIn, PKMX_WCHAR pklKey, PKMX_WCHAR pklOut); @@ -1474,7 +1622,7 @@ KMX_DWORD ProcessKeyLine(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode) pklKey = new KMX_WCHAR[GLOBAL_BUFSIZE]; pklOut = new KMX_WCHAR[GLOBAL_BUFSIZE]; if (!pklIn || !pklKey || !pklOut) - return CERR_CannotAllocateMemory; // forget about the little leak if pklKey or pklOut fail... + return KmnCompilerMessages::FATAL_CannotAllocateMemory; // forget about the little leak if pklKey or pklOut fail... KMX_DWORD result = ProcessKeyLineImpl(fk, str, IsUnicode, pklIn, pklKey, pklOut); @@ -1496,60 +1644,62 @@ KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnico pp = str; if (gp->fUsingKeys) { - if ((msg = GetXString(fk, str, u"+", pklIn, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if ((msg = GetXString(fk, str, u"+", pklIn, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != STATUS_Success) return msg; str = p + 1; - if ((msg = GetXString(fk, str, u">", pklKey, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if ((msg = GetXString(fk, str, u">", pklKey, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != STATUS_Success) return msg; - if (pklKey[0] == 0) return CERR_ZeroLengthString; + if (pklKey[0] == 0) return KmnCompilerMessages::ERROR_ZeroLengthString; if(Uni_IsSurrogate1(pklKey[0])) { // #11643: non-BMP characters do not makes sense for key codes - return CERR_NonBMPCharactersNotSupportedInKeySection; + return KmnCompilerMessages::ERROR_NonBMPCharactersNotSupportedInKeySection; } - if (xstrlen(pklKey) > 1) AddWarning(CWARN_KeyBadLength); + if (xstrlen(pklKey) > 1) { + ReportCompilerMessage(KmnCompilerMessages::WARN_KeyBadLength); + } } else { - if ((msg = GetXString(fk, str, u">", pklIn, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; - if (pklIn[0] == 0) return CERR_ZeroLengthString; + if ((msg = GetXString(fk, str, u">", pklIn, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != STATUS_Success) return msg; + if (pklIn[0] == 0) return KmnCompilerMessages::ERROR_ZeroLengthString; } str = p + 1; - if ((msg = GetXString(fk, str, u"c\n", pklOut, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != CERR_None) return msg; + if ((msg = GetXString(fk, str, u"c\n", pklOut, GLOBAL_BUFSIZE - 1, (int)(str - pp), &p, TRUE, IsUnicode)) != STATUS_Success) return msg; - if (pklOut[0] == 0) return CERR_ZeroLengthString; + if (pklOut[0] == 0) return KmnCompilerMessages::ERROR_ZeroLengthString; CheckContextStatementPositions(pklIn); // 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)) != STATUS_Success) return msg; // Test that use() statements are not followed by other content - if ((msg = CheckUseStatementsInOutput(pklOut)) != CERR_None) { + if ((msg = CheckUseStatementsInOutput(pklOut)) != STATUS_Success) { return msg; // I4867 } // Warn if virtual keys are used in the output, as they are unsupported by Core - if ((msg = CheckVirtualKeysInOutput(pklOut)) != CERR_None) { + if ((msg = CheckVirtualKeysInOutput(pklOut)) != STATUS_Success) { return msg; } if (gp->fReadOnly) { // Ensure no output is made from the rule, and that // use() statements meet required readonly semantics - if ((msg = CheckOutputIsReadonly(fk, pklOut)) != CERR_None) { + if ((msg = CheckOutputIsReadonly(fk, pklOut)) != STATUS_Success) { return msg; } // Inject `context` to start of output if group is readonly // to keep the output internally consistent - if ((msg = InjectContextToReadonlyOutput(pklOut)) != CERR_None) { + if ((msg = InjectContextToReadonlyOutput(pklOut)) != STATUS_Success) { return msg; } } if(!resizeKeyArray(gp)) { - return CERR_CannotAllocateMemory; + return KmnCompilerMessages::FATAL_CannotAllocateMemory; } kp = &gp->dpKeyArray[gp->cxKeyArray]; @@ -1571,19 +1721,19 @@ KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnico { kp->Key = 0; kp->ShiftFlags = 0; - return CERR_None; + return STATUS_Success; } // Expand each rule out into multiple rules - much faster processing at the key hit time - if (*pklKey == 0) return CERR_ZeroLengthString; + if (*pklKey == 0) return KmnCompilerMessages::ERROR_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; + if ((msg = ExpandKp(fk, kp, *(pklKey + 2) - 1)) != STATUS_Success) return msg; break; case CODE_EXTENDED: @@ -1592,7 +1742,7 @@ KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnico break; default: - return CERR_InvalidCodeInKeyPartOfRule; + return KmnCompilerMessages::ERROR_InvalidCodeInKeyPartOfRule; } else { @@ -1600,7 +1750,7 @@ KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnico kp->Key = *pklKey; } - return CERR_None; + return STATUS_Success; } @@ -1635,7 +1785,7 @@ KMX_DWORD ExpandKp_ReplaceIndex(PFILE_KEYBOARD fk, PFILE_KEY k, KMX_DWORD keyInd } } - return CERR_None; + return STATUS_Success; } @@ -1664,7 +1814,7 @@ KMX_DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, KMX_DWORD storeIndex) int offset = (int)(kpp - gp->dpKeyArray); if (!resizeKeyArray(gp, nchrs)) { - return CERR_CannotAllocateMemory; + return KmnCompilerMessages::FATAL_CannotAllocateMemory; } kpp = &gp->dpKeyArray[offset]; @@ -1687,11 +1837,11 @@ KMX_DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, KMX_DWORD storeIndex) k->ShiftFlags = *(pn + 2); break; default: - return CERR_CodeInvalidInKeyStore; + return KmnCompilerMessages::ERROR_CodeInvalidInKeyStore; } } else if(Uni_IsSurrogate1(*pn)) { // #11643: non-BMP characters do not makes sense for key codes - return CERR_NonBMPCharactersNotSupportedInKeySection; + return KmnCompilerMessages::ERROR_NonBMPCharactersNotSupportedInKeySection; } else { k->Key = *pn; // set the key to store offset. k->ShiftFlags = 0; @@ -1704,7 +1854,7 @@ KMX_DWORD ExpandKp(PFILE_KEYBOARD fk, PFILE_KEY kpp, KMX_DWORD storeIndex) delete[] dpContext; delete[] dpOutput; - return CERR_None; + return STATUS_Success; } /** @@ -1896,7 +2046,7 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if (mx >= max) { // This is an error condition, we want the compiler // to crash if we reach this - return CERR_BufferOverflow; + return KmnCompilerMessages::FATAL_BufferOverflow; } tokenFound = FALSE; @@ -1945,29 +2095,27 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX { case 99: if (tokenFound) break; - { - snprintf(ErrExtraLIB, ERR_EXTRA_LIB_LEN, "token: %c",(int)*p); - } - return CERR_InvalidToken; + // TODO: report an error about the missing token details --> "token: %c",(int)*p); + return KmnCompilerMessages::ERROR_InvalidToken; case 0: if (u16nicmp(p, u"deadkey", z = 7) == 0 || u16nicmp(p, u"dk", z = 2) == 0) { p += z; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidDeadkey; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidDeadkey; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_DEADKEY; - if (!StrValidChrs(q, DeadKeyChars)) return CERR_InvalidDeadkey; + if (!StrValidChrs(q, DeadKeyChars)) return KmnCompilerMessages::ERROR_InvalidDeadkey; tstr[mx++] = GetDeadKey(fk, q); //atoiW(q); 7-5-01: named deadkeys tstr[mx] = 0; } else { n = xatoi(&p); - if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; - if ((err = kmcmp::UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; + if (*p != '\0' && !iswspace(*p)) return KmnCompilerMessages::ERROR_InvalidValue; + if ((err = kmcmp::UTF32ToUTF16(n, &n1, &n2)) != STATUS_Success) return err; tstr[mx++] = n1; if (n2 >= 0) tstr[mx++] = n2; tstr[mx] = 0; @@ -1976,9 +2124,9 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX case 1: q = (PKMX_WCHAR) u16chr(p + 1, '\"'); - if (!q) return CERR_UnterminatedString; - if ((int)(q - p) - 1 + mx > max) return CERR_ExtendedStringTooLong; - if (sFlag) return CERR_StringInVirtualKeySection; + if (!q) return KmnCompilerMessages::ERROR_UnterminatedString; + if ((int)(q - p) - 1 + mx > max) return KmnCompilerMessages::ERROR_ExtendedStringTooLong; + if (sFlag) return KmnCompilerMessages::ERROR_StringInVirtualKeySection; u16ncat(tstr, p + 1, (int)(q - p) - 1); // I3481 mx += (int)(q - p) - 1; tstr[mx] = 0; @@ -1986,28 +2134,28 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX continue; case 2: q = (PKMX_WCHAR) u16chr(p + 1, '\''); - if (!q) return CERR_UnterminatedString; - if ((int)(q - p) - 1 + mx > max) return CERR_ExtendedStringTooLong; - if (sFlag) return CERR_StringInVirtualKeySection; + if (!q) return KmnCompilerMessages::ERROR_UnterminatedString; + if ((int)(q - p) - 1 + mx > max) return KmnCompilerMessages::ERROR_ExtendedStringTooLong; + if (sFlag) return KmnCompilerMessages::ERROR_StringInVirtualKeySection; u16ncat(tstr, p + 1, (int)(q - p) - 1); // I3481 mx += (int)(q - p) - 1; tstr[mx] = 0; p = q + 1; continue; case 3: - if (u16nicmp(p, u"any", 3) != 0) return CERR_InvalidToken; - if (sFlag) return CERR_AnyInVirtualKeySection; + if (u16nicmp(p, u"any", 3) != 0) return KmnCompilerMessages::ERROR_InvalidToken; + if (sFlag) return KmnCompilerMessages::ERROR_AnyInVirtualKeySection; p += 3; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidAny; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidAny; for (i = 0; i < fk->cxStoreArray; i++) { if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; - if (!*fk->dpStoreArray[i].dpString) return CERR_ZeroLengthString; + if (!*fk->dpStoreArray[i].dpString) return KmnCompilerMessages::ERROR_ZeroLengthString; kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); tstr[mx++] = UC_SENTINEL; @@ -2018,7 +2166,7 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX case 4: if (u16nicmp(p, u"beep", 4) == 0) { - if (sFlag) return CERR_BeepInVirtualKeySection; + if (sFlag) return KmnCompilerMessages::ERROR_BeepInVirtualKeySection; p += 4; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_BEEP; @@ -2026,56 +2174,60 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } else if (u16nicmp(p, u"baselayout", 10) == 0) // I3430 { - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); - if (sFlag) return CERR_InvalidInVirtualKeySection; + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + return KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores; + } + if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 10; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidToken; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidToken; err = process_baselayout(fk, q, tstr, &mx); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; } else - return CERR_InvalidToken; + return KmnCompilerMessages::ERROR_InvalidToken; continue; case 5: if (u16nicmp(p, u"if", 2) == 0) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); - if (sFlag) return CERR_InvalidInVirtualKeySection; + if(!VerifyKeyboardVersion(fk, VERSION_80)) { + return KmnCompilerMessages::ERROR_80FeatureOnly; + } + if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 2; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidIf; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidIf; err = process_if(fk, q, tstr, &mx); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; } else { - if (u16nicmp(p, u"index", 5) != 0) return CERR_InvalidToken; - if (sFlag) return CERR_IndexInVirtualKeySection; + if (u16nicmp(p, u"index", 5) != 0) return KmnCompilerMessages::ERROR_InvalidToken; + if (sFlag) return KmnCompilerMessages::ERROR_IndexInVirtualKeySection; p += 5; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidIndex; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidIndex; { KMX_WCHAR *context = NULL; KMX_WCHAR sep_com[3] = u" ,"; PKMX_WCHAR p_sep_com = sep_com; r = u16tok(q, p_sep_com, &context); // I3481 - if (!r) return CERR_InvalidIndex; + if (!r) return KmnCompilerMessages::ERROR_InvalidIndex; for (i = 0; i < fk->cxStoreArray; i++) { if (u16icmp(r, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); r = u16tok(NULL, p_sep_com, &context); // I3481 - if (!r || !*r || !isIntegerWstring(r) || atoiW(r) < 1) return CERR_InvalidIndex; + if (!r || !*r || !isIntegerWstring(r) || atoiW(r) < 1) return KmnCompilerMessages::ERROR_InvalidIndex; } tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_INDEX; @@ -2086,17 +2238,17 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } continue; case 6: - if (u16nicmp(p, u"outs", 4) != 0) return CERR_InvalidToken; - if (sFlag) return CERR_OutsInVirtualKeySection; + if (u16nicmp(p, u"outs", 4) != 0) return KmnCompilerMessages::ERROR_InvalidToken; + if (sFlag) return KmnCompilerMessages::ERROR_OutsInVirtualKeySection; p += 4; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidOuts; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidOuts; for (i = 0; i < fk->cxStoreArray; i++) { if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); @@ -2104,7 +2256,7 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX { tstr[mx++] = *q; if (mx >= max - 1) { - return CERR_OutsTooLong; + return KmnCompilerMessages::ERROR_OutsTooLong; } } tstr[mx] = 0; @@ -2113,16 +2265,18 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if (iswspace(*(p + 1))) break; // is a comment -- pre-stripped - so why this test? if (u16nicmp(p, u"context", 7) == 0) { - if (sFlag) return CERR_ContextInVirtualKeySection; + if (sFlag) return KmnCompilerMessages::ERROR_ContextInVirtualKeySection; p += 7; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); if (q && *q) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_Contextn); + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + return KmnCompilerMessages::ERROR_60FeatureOnly_Contextn; + } int n1b; n1b = atoiW(q); - if (n1b < 1 || n1b >= 0xF000) return CERR_InvalidToken; + if (n1b < 1 || n1b >= 0xF000) return KmnCompilerMessages::ERROR_InvalidToken; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_CONTEXTEX; tstr[mx++] = n1b; @@ -2144,21 +2298,23 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } else if (u16nicmp(p, u"call", 4) == 0) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_501, CERR_501FeatureOnly_Call); - if (sFlag) return CERR_CallInVirtualKeySection; + if(!VerifyKeyboardVersion(fk, VERSION_501)) { + return KmnCompilerMessages::ERROR_501FeatureOnly_Call; + } + if (sFlag) return KmnCompilerMessages::ERROR_CallInVirtualKeySection; p += 4; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidCall; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidCall; for (i = 0; i < fk->cxStoreArray; i++) { if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if (!kmcmp::IsValidCallStore(&fk->dpStoreArray[i])) return CERR_InvalidCall; + if (!kmcmp::IsValidCallStore(&fk->dpStoreArray[i])) return KmnCompilerMessages::ERROR_InvalidCall; kmcmp::CheckStoreUsage(fk, i, FALSE, FALSE, TRUE); - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_CALL; tstr[mx++] = (KMX_WCHAR)i + 1; @@ -2167,22 +2323,24 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX fk->dpStoreArray[i].dwSystemID = TSS_CALLDEFINITION; } else - return CERR_InvalidToken; + return KmnCompilerMessages::ERROR_InvalidToken; continue; case 8: if (u16nicmp(p, u"notany", 6) == 0) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly) - if (sFlag) return CERR_AnyInVirtualKeySection; + if(!VerifyKeyboardVersion(fk, VERSION_70)) { + return KmnCompilerMessages::ERROR_70FeatureOnly; + } + if (sFlag) return KmnCompilerMessages::ERROR_AnyInVirtualKeySection; p += 6; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidAny; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidAny; for (i = 0; i < fk->cxStoreArray; i++) { if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_NOTANY; @@ -2190,7 +2348,7 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX tstr[mx] = 0; continue; } - if (u16nicmp(p, u"nul", 3) != 0) return CERR_InvalidToken; + if (u16nicmp(p, u"nul", 3) != 0) return KmnCompilerMessages::ERROR_InvalidToken; p += 3; tstr[mx++] = UC_SENTINEL; @@ -2203,41 +2361,45 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if (*(p + 1) == '+') { n = xatoi(&p); - if (*p != '\0' && !iswspace(*p)) return CERR_InvalidValue; - if ((err = kmcmp::UTF32ToUTF16(n, &n1, &n2)) != CERR_None) return err; + if (*p != '\0' && !iswspace(*p)) return KmnCompilerMessages::ERROR_InvalidValue; + if ((err = kmcmp::UTF32ToUTF16(n, &n1, &n2)) != STATUS_Success) return err; tstr[mx++] = n1; if (n2 >= 0) tstr[mx++] = n2; tstr[mx] = 0; - if (!isUnicode) AddWarning(CWARN_UnicodeInANSIGroup); + if (!isUnicode) { + ReportCompilerMessage(KmnCompilerMessages::WARN_UnicodeInANSIGroup); + } continue; } - return CERR_InvalidToken; + return KmnCompilerMessages::ERROR_InvalidToken; } p += 3; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidUse; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidUse; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_USE; tstr[mx] = GetGroupNum(fk, q); - if (tstr[mx] == 0) return CERR_GroupDoesNotExist; + if (tstr[mx] == 0) return KmnCompilerMessages::ERROR_GroupDoesNotExist; tstr[++mx] = 0; continue; case 10: if (u16nicmp(p, u"reset", 5) == 0) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); - if (sFlag) return CERR_InvalidInVirtualKeySection; + if(!VerifyKeyboardVersion(fk, VERSION_80)) { + return KmnCompilerMessages::ERROR_80FeatureOnly; + } + if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 5; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidReset; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidReset; err = process_reset(fk, q, tstr, &mx); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; } else { - if (u16nicmp(p, u"return", 6) != 0) return CERR_InvalidToken; + if (u16nicmp(p, u"return", 6) != 0) return KmnCompilerMessages::ERROR_InvalidToken; p += 6; tstr[mx++] = UC_SENTINEL; @@ -2302,17 +2464,23 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } while (!finished); if ((sFlag & (LCTRLFLAG | LALTFLAG)) && (sFlag & (RCTRLFLAG | RALTFLAG))) { - AddWarning(CWARN_MixingLeftAndRightModifiers); + ReportCompilerMessage(KmnCompilerMessages::WARN_MixingLeftAndRightModifiers); } - // If we use chiral modifiers, or we use state keys, and we target web in the keyboard, and we don't manually specify a keyboard version, bump the minimum - // version to 10.0. This makes an assumption that if we are using these features in a keyboard and it has no version specified, that we want to use the features - // in the web target platform, even if there are platform() rules excluding this possibility. In that (rare) situation, the keyboard developer should simply specify - // the &version to be 9.0 or whatever to avoid this behaviour. + // If we use chiral modifiers, or we use state keys, and we target web in + // the keyboard, and we don't manually specify a keyboard version, bump + // the minimum version to 10.0. This makes an assumption that if we are + // using these features in a keyboard and it has no version specified, + // that we want to use the features in the web target platform, even if + // there are platform() rules excluding this possibility. In that (rare) + // situation, the keyboard developer should simply specify the &version to + // be 9.0 or whatever to avoid this behaviour. if (sFlag & (LCTRLFLAG | LALTFLAG | RCTRLFLAG | RALTFLAG | CAPITALFLAG | NOTCAPITALFLAG | NUMLOCKFLAG | NOTNUMLOCKFLAG | SCROLLFLAG | NOTSCROLLFLAG) && kmcmp::CompileTarget == CKF_KEYMANWEB && fk->dwFlags & KF_AUTOMATICVERSION) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_100, 0); + if(!VerifyKeyboardVersion(fk, VERSION_100)) { + return STATUS_Success; + } } //printf("sFlag: %x\n", sFlag); @@ -2326,33 +2494,37 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX 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 + return KmnCompilerMessages::ERROR_InvalidToken; // I3137 - key portion of VK is missing e.g. "[CTRL ALT]", this generates invalid kmx file that can crash Keyman or compiler later on // I3511 } while (*q != ']') { if (*q == '\'' || *q == '"') { - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_VirtualCharKey); - if (!kmcmp::FMnemonicLayout) AddWarning(CWARN_VirtualCharKeyWithPositionalLayout); + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + return KmnCompilerMessages::ERROR_60FeatureOnly_VirtualCharKey; + } + if (!kmcmp::FMnemonicLayout) { + ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualCharKeyWithPositionalLayout); + } KMX_WCHAR chQuote = *q; - q++; if (*q == chQuote || *q == '\n' || *q == 0) return CERR_InvalidToken; + q++; if (*q == chQuote || *q == '\n' || *q == 0) return KmnCompilerMessages::ERROR_InvalidToken; tstr[mx - 1] |= VIRTUALCHARKEY; tstr[mx++] = *q; - q++; if (*q != chQuote) return CERR_InvalidToken; + q++; if (*q != chQuote) return KmnCompilerMessages::ERROR_InvalidToken; q++; while (iswspace(*q)) q++; - if (*q != ']') return CERR_InvalidToken; + if (*q != ']') return KmnCompilerMessages::ERROR_InvalidToken; break; /* out of while loop */ } for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); - if (*q == 0) return CERR_InvalidToken; + if (*q == 0) return KmnCompilerMessages::ERROR_InvalidToken; KMX_WCHAR vkname[SZMAX_VKDICTIONARYNAME]; // I3438 - if (j >= SZMAX_VKDICTIONARYNAME) return CERR_InvalidToken; + if (j >= SZMAX_VKDICTIONARYNAME) return KmnCompilerMessages::ERROR_InvalidToken; u16ncpy(vkname, p, j); // I3481 vkname[j] = 0; @@ -2370,18 +2542,22 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if (i == VK__MAX + 1) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_InvalidToken); + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + return KmnCompilerMessages::ERROR_InvalidToken; + } i = GetVKCode(fk, vkname); // I3438 if (i == 0) - return CERR_InvalidToken; + return KmnCompilerMessages::ERROR_InvalidToken; } p = q; tstr[mx++] = (int)i; - if (kmcmp::FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) AddWarning(CWARN_VirtualKeyWithMnemonicLayout); // I3438 + if (kmcmp::FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) { + ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualKeyWithMnemonicLayout); // I3438 + } while (iswspace(*q)) q++; } @@ -2397,30 +2573,34 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX case 14: if (u16nicmp(p, u"set", 3) == 0) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + if(!VerifyKeyboardVersion(fk, VERSION_80)) { + return KmnCompilerMessages::ERROR_80FeatureOnly; + } p += 3; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidSet; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidSet; err = process_set(fk, q, tstr, &mx); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; } else if (u16nicmp(p, u"save", 4) == 0) { - VERIFY_KEYBOARD_VERSION(fk, VERSION_80, CERR_80FeatureOnly); + if(!VerifyKeyboardVersion(fk, VERSION_80)) { + return KmnCompilerMessages::ERROR_80FeatureOnly; + } p += 4; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidSave; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidSave; err = process_save(fk, q, tstr, &mx); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; } else { - if (u16nicmp(p, u"switch", 6) != 0) return CERR_InvalidToken; + if (u16nicmp(p, u"switch", 6) != 0) return KmnCompilerMessages::ERROR_InvalidToken; p += 6; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidSwitch; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidSwitch; tstr[mx++] = UC_SENTINEL; tstr[mx++] = CODE_SWITCH; tstr[mx++] = atoiW(q); @@ -2436,16 +2616,18 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX tstr[mx] = 0; } else - return CERR_InvalidToken; + return KmnCompilerMessages::ERROR_InvalidToken; continue; case 16: - VERIFY_KEYBOARD_VERSION(fk, VERSION_60, CERR_60FeatureOnly_NamedCodes); + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + return KmnCompilerMessages::ERROR_60FeatureOnly_NamedCodes; + } q = p + 1; while (*q && !iswspace(*q)) q++; c = *q; *q = 0; n = kmcmp::CodeConstants->GetCode(p + 1, &i); *q = c; - if (n == 0) return CERR_InvalidNamedCode; + if (n == 0) return KmnCompilerMessages::ERROR_InvalidNamedCode; if (i < 0xFFFFFFFFL) kmcmp::CheckStoreUsage(fk, i, TRUE, FALSE, FALSE); // I2993 if (n > 0xFFFF) { @@ -2458,34 +2640,38 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX p = q; continue; case 17: - if (u16nicmp(p, u"platform", 8) != 0) return CERR_InvalidToken; // I3430 - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); - if (sFlag) return CERR_InvalidInVirtualKeySection; + if (u16nicmp(p, u"platform", 8) != 0) return KmnCompilerMessages::ERROR_InvalidToken; // I3430 + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + return KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores; + } + if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 8; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidToken; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidToken; err = process_platform(fk, q, tstr, &mx); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; continue; case 18: // I3437 - if (u16nicmp(p, u"layer", 5) != 0) return CERR_InvalidToken; - VERIFY_KEYBOARD_VERSION(fk, VERSION_90, CERR_90FeatureOnly_SetSystemStores); - if (sFlag) return CERR_InvalidInVirtualKeySection; + if (u16nicmp(p, u"layer", 5) != 0) return KmnCompilerMessages::ERROR_InvalidToken; + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + return KmnCompilerMessages::ERROR_90FeatureOnly_SetSystemStores; + } + if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 5; q = GetDelimitedString(&p, u"()", GDS_CUTLEAD | GDS_CUTFOLL); - if (!q || !*q) return CERR_InvalidToken; + if (!q || !*q) return KmnCompilerMessages::ERROR_InvalidToken; err = process_set_synonym(TSS_LAYER, fk, q, tstr, &mx); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; continue; case 19: // #2241 - if (*(p + 1) != '.') return CERR_InvalidToken; - if (sFlag) return CERR_InvalidInVirtualKeySection; + if (*(p + 1) != '.') return KmnCompilerMessages::ERROR_InvalidToken; + if (sFlag) return KmnCompilerMessages::ERROR_InvalidInVirtualKeySection; p += 2; err = process_expansion(fk, p, tstr, &mx, max); - if (err != CERR_None) return err; + if (err != STATUS_Success) return err; continue; default: - return CERR_InvalidToken; + return KmnCompilerMessages::ERROR_InvalidToken; } if (tokenFound) { @@ -2493,7 +2679,7 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX u16ncpy(output, tstr, max); // I3481 output[max - 1] = 0; ErrChr = 0; - return CERR_None; + return STATUS_Success; } } while (*p); @@ -2503,10 +2689,10 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX u16ncpy(output, tstr, max); // I3481 output[max - 1] = 0; ErrChr = 0; - return CERR_None; + return STATUS_Success; } - return CERR_NoTokensFound; + return KmnCompilerMessages::ERROR_NoTokensFound; } KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx); // I3430 @@ -2531,7 +2717,7 @@ KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR PKMX_WCHAR r; - if ((msg = GetXString(fk, q, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, q, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != STATUS_Success) { delete[] temp; return msg; @@ -2539,12 +2725,14 @@ KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR KMX_DWORD dwStoreID; - if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) - { + if (!AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) { delete[] temp; - return msg; + // TODO: redundant error + return KmnCompilerMessages::ERROR_InvalidIf; } + delete[] temp; + tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = (KMX_WCHAR)CODE_IFSYSTEMSTORE; tstr[(*mx)++] = (KMX_WCHAR)(dwSystemID + 1); // I4785 @@ -2552,9 +2740,7 @@ KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; - delete[] temp; - - return CERR_None; + return STATUS_Success; } KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // I3431 @@ -2572,7 +2758,7 @@ KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) nnot = TRUE; } - if (*s != '=') return CERR_InvalidIf; + if (*s != '=') return KmnCompilerMessages::ERROR_InvalidIf; s++; while (*s == ' ') s++; *r = 0; @@ -2580,12 +2766,14 @@ KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) if (r[0] == '&') { - VERIFY_KEYBOARD_VERSION( fk, VERSION_90, CERR_90FeatureOnly_IfSystemStores); + if(!VerifyKeyboardVersion( fk, VERSION_90)) { + return KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores; + } for (i = 0; StoreTokens[i]; i++) { if (u16icmp(r, StoreTokens[i]) == 0) break; } - if (!StoreTokens[i]) return CERR_IfSystemStore_NotFound; + if (!StoreTokens[i]) return KmnCompilerMessages::ERROR_IfSystemStore_NotFound; code = CODE_IFSYSTEMSTORE; } else @@ -2596,7 +2784,7 @@ KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) { if (u16icmp(r, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); } @@ -2604,7 +2792,7 @@ KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) KMX_DWORD msg; - if ((msg = GetXString(fk, s, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, s, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != STATUS_Success) { delete[] temp; return msg; @@ -2612,12 +2800,14 @@ KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) KMX_DWORD dwStoreID; - if ((msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) != CERR_None) - { + if (!AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) { delete[] temp; - return msg; + // TODO: redundant error + return KmnCompilerMessages::ERROR_InvalidIf; } + delete[] temp; + tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = (KMX_WCHAR)code; tstr[(*mx)++] = (KMX_WCHAR)(i + 1); @@ -2625,7 +2815,7 @@ KMX_DWORD process_if(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; - return CERR_None; + return STATUS_Success; } KMX_DWORD process_reset(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) @@ -2636,7 +2826,7 @@ KMX_DWORD process_reset(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *m { if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); tstr[(*mx)++] = UC_SENTINEL; @@ -2644,7 +2834,7 @@ KMX_DWORD process_reset(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *m tstr[(*mx)++] = (KMX_WCHAR)(i + 1); tstr[(*mx)] = 0; - return CERR_None; + return STATUS_Success; } KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx, int max) { @@ -2654,13 +2844,13 @@ KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, in KMX_DWORD BaseChar=0; if (*mx == 0) { - return CERR_ExpansionMustFollowCharacterOrVKey; + return KmnCompilerMessages::ERROR_ExpansionMustFollowCharacterOrVKey; } PKMX_WCHAR p = &tstr[*mx]; p = decxstr(p, tstr); if (*p == UC_SENTINEL) { if (*(p + 1) != CODE_EXTENDED) { - return CERR_ExpansionMustFollowCharacterOrVKey; + return KmnCompilerMessages::ERROR_ExpansionMustFollowCharacterOrVKey; } isVKey = TRUE; BaseKey = *(p + 3); @@ -2676,7 +2866,7 @@ KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, in KMX_DWORD msg; - if ((msg = GetXString(fk, q, u"", temp, (KMX_DWORD)_countof(temp) - 1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, q, u"", temp, (KMX_DWORD)_countof(temp) - 1, 0, &r, FALSE, TRUE)) != STATUS_Success) { return msg; } @@ -2686,25 +2876,25 @@ KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, in switch(temp[0]) { case 0: - return isVKey ? CERR_VKeyExpansionMustBeFollowedByVKey : CERR_CharacterExpansionMustBeFollowedByCharacter; + return isVKey ? KmnCompilerMessages::ERROR_VKeyExpansionMustBeFollowedByVKey : KmnCompilerMessages::ERROR_CharacterExpansionMustBeFollowedByCharacter; case UC_SENTINEL: // Verify that range is valid virtual key range if(!isVKey) { - return CERR_CharacterExpansionMustBeFollowedByCharacter; + return KmnCompilerMessages::ERROR_CharacterExpansionMustBeFollowedByCharacter; } if (temp[1] != CODE_EXTENDED) { - return CERR_VKeyExpansionMustBeFollowedByVKey; + return KmnCompilerMessages::ERROR_VKeyExpansionMustBeFollowedByVKey; } HighKey = temp[3], HighShiftFlags = temp[2]; if (HighShiftFlags != BaseShiftFlags) { - return CERR_VKeyExpansionMustUseConsistentShift; + return KmnCompilerMessages::ERROR_VKeyExpansionMustUseConsistentShift; } if (HighKey <= BaseKey) { - return CERR_ExpansionMustBePositive; + return KmnCompilerMessages::ERROR_ExpansionMustBePositive; } // Verify space in buffer if (*mx + (HighKey - BaseKey) * 5 + 1 >= max) { - return CERR_VirtualKeyExpansionTooLong; + return KmnCompilerMessages::ERROR_VirtualKeyExpansionTooLong; } // Inject an expansion. for (BaseKey++; BaseKey < HighKey; BaseKey++) { @@ -2720,12 +2910,12 @@ KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, in default: // Verify that range is a valid character range if (isVKey) { - return CERR_VKeyExpansionMustBeFollowedByVKey; + return KmnCompilerMessages::ERROR_VKeyExpansionMustBeFollowedByVKey; } HighChar = Uni_UTF16ToUTF32(temp); if (HighChar <= BaseChar) { - return CERR_ExpansionMustBePositive; + return KmnCompilerMessages::ERROR_ExpansionMustBePositive; } // Inject an expansion. for (BaseChar++; BaseChar < HighChar; BaseChar++) { @@ -2733,14 +2923,14 @@ KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, in if (Uni_IsSMP(BaseChar)) { // We'll test on each char to avoid complex calculations crossing SMP boundary if (*mx + 3 >= max) { - return CERR_CharacterRangeTooLong; + return KmnCompilerMessages::ERROR_CharacterRangeTooLong; } tstr[(*mx)++] = (KMX_WCHAR) Uni_UTF32ToSurrogate1(BaseChar); tstr[(*mx)++] = (KMX_WCHAR) Uni_UTF32ToSurrogate2(BaseChar); } else { if (*mx + 2 >= max) { - return CERR_CharacterRangeTooLong; + return KmnCompilerMessages::ERROR_CharacterRangeTooLong; } tstr[(*mx)++] = (KMX_WCHAR) BaseChar; } @@ -2748,7 +2938,7 @@ KMX_DWORD process_expansion(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, in tstr[*mx] = 0; } - return CERR_None; + return STATUS_Success; } KMX_DWORD process_set_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) // I3437 @@ -2757,7 +2947,7 @@ KMX_DWORD process_set_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHA PKMX_WCHAR temp = new KMX_WCHAR[GLOBAL_BUFSIZE], r; KMX_DWORD msg; - if ((msg = GetXString(fk, q, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, q, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != STATUS_Success) { delete[] temp; return msg; @@ -2765,16 +2955,20 @@ KMX_DWORD process_set_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHA KMX_DWORD dwStoreID; - msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); + if(!AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) { + delete[] temp; + // TODO: redundant error + return KmnCompilerMessages::ERROR_InvalidSet; + } + delete[] temp; - if (msg != CERR_None) return msg; tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = (KMX_WCHAR)CODE_SETSYSTEMSTORE; tstr[(*mx)++] = (KMX_WCHAR)(dwSystemID + 1); tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; - return CERR_None; + return STATUS_Success; } KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) @@ -2784,7 +2978,7 @@ KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) while (*s && *s != u' ' && *s != u'=') s++; r = s; while (*s == u' ') s++; - if (*s != '=') return CERR_InvalidSet; + if (*s != '=') return KmnCompilerMessages::ERROR_InvalidSet; s++; while (*s == ' ') s++; *r = 0; @@ -2794,12 +2988,14 @@ KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) if (r[0] == '&') { - VERIFY_KEYBOARD_VERSION((PFILE_KEYBOARD) fk, VERSION_90, CERR_90FeatureOnly_SetSystemStores); // I3437 + if(!VerifyKeyboardVersion(fk, VERSION_90)) { + return KmnCompilerMessages::ERROR_90FeatureOnly_SetSystemStores; // I3437 + } for (i = 0; StoreTokens[i]; i++) { if (u16icmp(r, StoreTokens[i]) == 0) break; } - if (!StoreTokens[i]) return CERR_SetSystemStore_NotFound; + if (!StoreTokens[i]) return KmnCompilerMessages::ERROR_SetSystemStore_NotFound; code = CODE_SETSYSTEMSTORE; } else @@ -2812,7 +3008,7 @@ KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) { if (u16icmp(r2, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); code = CODE_SETOPT; } @@ -2823,7 +3019,7 @@ KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) //r = wcstok(NULL, L" ="); - if ((msg = GetXString(fk, s, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != CERR_None) + if ((msg = GetXString(fk, s, u"", temp, GLOBAL_BUFSIZE - 1, 0, &r, FALSE, TRUE)) != STATUS_Success) { delete[] temp; return msg; @@ -2831,16 +3027,20 @@ KMX_DWORD process_set(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) KMX_DWORD dwStoreID; - msg = AddStore(fk, TSS_COMPARISON, temp, &dwStoreID); + if(!AddStore(fk, TSS_COMPARISON, temp, &dwStoreID)) { + delete[] temp; + // TODO: redundant error + return KmnCompilerMessages::ERROR_InvalidSet; + } + delete[] temp; - if (msg != CERR_None) return msg; tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = (KMX_WCHAR)code; tstr[(*mx)++] = (KMX_WCHAR)(i + 1); tstr[(*mx)++] = (KMX_WCHAR)(dwStoreID + 1); tstr[(*mx)] = 0; - return CERR_None; + return STATUS_Success; } KMX_DWORD process_save(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx) @@ -2851,14 +3051,14 @@ KMX_DWORD process_save(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx { if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break; } - if (i == fk->cxStoreArray) return CERR_StoreDoesNotExist; + if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist; kmcmp::CheckStoreUsage(fk, i, FALSE, TRUE, FALSE); tstr[(*mx)++] = UC_SENTINEL; tstr[(*mx)++] = CODE_SAVEOPT; tstr[(*mx)++] = (KMX_WCHAR)(i + 1); tstr[(*mx)] = 0; - return CERR_None; + return STATUS_Success; } int xatoi(PKMX_WCHAR *p) @@ -2908,21 +3108,21 @@ int GetGroupNum(PFILE_KEYBOARD fk, PKMX_WCHAR p) KMX_DWORD ProcessEthnologueStore(PKMX_WCHAR p) // I2646 { - KMX_DWORD res = CERR_None; + KMX_DWORD res = STATUS_Success; PKMX_WCHAR q = NULL; while (*p) { while (u16chr(u" ,;", *p)) { - if (*p != ' ') res = CWARN_PunctuationInEthnologueCode; + if (*p != ' ') res = KmnCompilerMessages::WARN_PunctuationInEthnologueCode; p++; } - if (q == p) return CERR_InvalidEthnologueCode; + if (q == p) return KmnCompilerMessages::ERROR_InvalidEthnologueCode; if (*p) { for (int i = 0; i < 3; i++) { - if (!iswalpha(*p)) return CERR_InvalidEthnologueCode; + if (!iswalpha(*p)) return KmnCompilerMessages::ERROR_InvalidEthnologueCode; p++; } } @@ -2948,7 +3148,7 @@ KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) // Convert virtual key to hotkey (different bitflags) if (ShiftFlags & ~K_HOTKEYSHIFTFLAGS) { - AddWarning(CWARN_HotkeyHasInvalidModifier); + ReportCompilerMessage(KmnCompilerMessages::WARN_HotkeyHasInvalidModifier); } if (ShiftFlags & K_SHIFTFLAG) *hk |= HK_SHIFT; @@ -2957,7 +3157,7 @@ KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) *hk |= Key; - return CERR_None; + return STATUS_Success; } q = (PKMX_WCHAR) u16chr(p, '['); @@ -2973,7 +3173,7 @@ KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) if (u16nicmp(q, u"ALT", 3) == 0) sFlag |= HK_ALT, q += 3; else if (u16nicmp(q, u"CTRL", 4) == 0) sFlag |= HK_CTRL, q += 4; else if (u16nicmp(q, u"SHIFT", 5) == 0) sFlag |= HK_SHIFT, q += 5; - else if (towupper(*q) != 'K') return CERR_InvalidToken; + else if (towupper(*q) != 'K') return KmnCompilerMessages::ERROR_InvalidToken; } while (towupper(*q) != 'K'); r = (PKMX_WCHAR) u16chr(q, ']'); @@ -2983,18 +3183,18 @@ KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) while (iswspace(*r) && r > q) r--; r++; } - else return CERR_NoTokensFound; + else return KmnCompilerMessages::ERROR_NoTokensFound; j = (int)(r - q); for (i = 0; i <= VK__MAX; i++) // I3438 if (j == (int) u16len(VKeyNames[i]) && u16nicmp(q, VKeyNames[i], j) == 0) break; - if (i == VK__MAX + 1) return CERR_InvalidToken; // I3438 + if (i == VK__MAX + 1) return KmnCompilerMessages::ERROR_InvalidToken; // I3438 *hk = i | sFlag; - return CERR_None; + return STATUS_Success; } q = GetDelimitedString(&p, u"\"\"", GDS_CUTLEAD | GDS_CUTFOLL); @@ -3005,10 +3205,10 @@ KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) if (u16chr(q, '%')) *hk |= HK_ALT; q = (PKMX_WCHAR) u16chr(q, 0) - 1; *hk |= *q; - return CERR_None; + return STATUS_Success; } - return CERR_CodeInvalidInThisSection; + return KmnCompilerMessages::ERROR_CodeInvalidInThisSection; } @@ -3019,29 +3219,24 @@ void SetChecksum(PKMX_BYTE buf, PKMX_DWORD CheckSum, KMX_DWORD sz) } -KMX_BOOL kmcmp::CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall) -{ +void kmcmp::CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall) { PFILE_STORE sp = &fk->dpStoreArray[storeIndex]; - if (fIsStore && !sp->fIsStore) - { - if (sp->fIsDebug || sp->fIsOption || sp->fIsReserved || sp->fIsCall) - AddWarningBool(CWARN_StoreAlreadyUsedAsOptionOrCall); + if (fIsStore && !sp->fIsStore) { + if (sp->fIsDebug || sp->fIsOption || sp->fIsReserved || sp->fIsCall) { + ReportCompilerMessage(KmnCompilerMessages::WARN_StoreAlreadyUsedAsOptionOrCall); + } sp->fIsStore = TRUE; - } - else if (fIsOption && !sp->fIsOption) - { - if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsCall) - AddWarningBool(CWARN_StoreAlreadyUsedAsStoreOrCall); + } else if (fIsOption && !sp->fIsOption) { + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsCall) { + ReportCompilerMessage(KmnCompilerMessages::WARN_StoreAlreadyUsedAsStoreOrCall); + } sp->fIsOption = TRUE; - } - else if (fIsCall && !sp->fIsCall) - { - if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsOption) - AddWarningBool(CWARN_StoreAlreadyUsedAsStoreOrOption); + } else if (fIsCall && !sp->fIsCall) { + if (sp->fIsDebug || sp->fIsStore || sp->fIsReserved || sp->fIsOption) { + ReportCompilerMessage(KmnCompilerMessages::WARN_StoreAlreadyUsedAsStoreOrOption); + } sp->fIsCall = TRUE; } - - return TRUE; } KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataSize) @@ -3094,7 +3289,7 @@ KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataS } buf = new KMX_BYTE[size]; - if (!buf) return CERR_CannotAllocateMemory; + if (!buf) return KmnCompilerMessages::FATAL_CannotAllocateMemory; memset(buf, 0, size); ck = (PCOMP_KEYBOARD)buf; @@ -3210,7 +3405,7 @@ KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataS if (offset != size) { delete[] buf; - return CERR_SomewhereIGotItWrong; + return KmnCompilerMessages::FATAL_SomewhereIGotItWrong; } SetChecksum(buf, &ck->dwCheckSum, (KMX_DWORD)size); @@ -3218,7 +3413,7 @@ KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataS *data = buf; dataSize = size; - return CERR_None; + return STATUS_Success; } KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess) @@ -3231,7 +3426,7 @@ KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_B KMX_WCHAR str[LINESIZE + 3]; if(offset >= sz) { - return CERR_EndOfFile; + return STATUS_EndOfFile; } len = offset + LINESIZE*2 > sz ? sz-offset : LINESIZE*2; @@ -3247,7 +3442,7 @@ KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_B } if (len == 0) { - return CERR_EndOfFile; + return STATUS_EndOfFile; } @@ -3259,7 +3454,7 @@ KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_B { *p = 0; // I2525 u16ncpy(wstr, str, LINESIZE); // I3481 - return (PreProcess ? CERR_None : CERR_UnterminatedString); + return (PreProcess ? STATUS_Success : KmnCompilerMessages::ERROR_UnterminatedString); } if (*p == currentQuotes) currentQuotes = 0; continue; @@ -3291,7 +3486,7 @@ KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_B } *p = 0; // I2525 u16ncpy(wstr, str, LINESIZE); // I3481 - return (PreProcess ? CERR_None : CERR_InvalidLineContinuation); + return (PreProcess ? STATUS_Success : KmnCompilerMessages::ERROR_InvalidLineContinuation); } if (*p == L'\n') break; @@ -3320,7 +3515,7 @@ KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_B str[LINESIZE - 1] = 0; // I2525 u16ncpy(wstr, str, LINESIZE); // I3481 if (len == LINESIZE) - return (PreProcess ? CERR_None : CERR_LineTooLong); + return (PreProcess ? STATUS_Success : KmnCompilerMessages::ERROR_LineTooLong); } kmcmp::currentLine++; @@ -3339,7 +3534,7 @@ KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_B // trim spaces now, why not? u16ncpy(wstr, str, LINESIZE); // I3481 - return CERR_None; + return STATUS_Success; } KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, int offset, int IsUnicode) @@ -3347,7 +3542,7 @@ KMX_DWORD GetRHS(PFILE_KEYBOARD fk, PKMX_WCHAR p, PKMX_WCHAR buf, int bufsize, i PKMX_WCHAR q; p = (const PKMX_WCHAR) u16chr(p, '>'); - if (!p) return CERR_NoTokensFound; + if (!p) return KmnCompilerMessages::ERROR_NoTokensFound; p++; @@ -3384,35 +3579,34 @@ KMX_DWORD ImportBitmapFile(PFILE_KEYBOARD fk, PKMX_WCHAR szName, PKMX_DWORD File { auto szNameUtf8 = string_from_u16string(szName); - if(!loadfileproc(szNameUtf8.c_str(), fk->extra->kmnFilename.c_str(), nullptr, (int*) FileSize, msgprocContext)) { + std::vector bufvec = loadfileproc(szNameUtf8, fk->extra->kmnFilename); + if(!bufvec.size()) { // Append .bmp and try again if(endsWith(szNameUtf8, ".bmp")) { - return CERR_CannotReadBitmapFile; + return KmnCompilerMessages::ERROR_CannotReadBitmapFile; } szNameUtf8.append(".bmp"); - if(!loadfileproc(szNameUtf8.c_str(), fk->extra->kmnFilename.c_str(), nullptr, (int*) FileSize, msgprocContext)) { - return CERR_CannotReadBitmapFile; - } + bufvec = loadfileproc(szNameUtf8, fk->extra->kmnFilename); } - if(*FileSize < 2) { + if(bufvec.size() < 2) { // Zero-byte file is invalid; 2 byte file is too, but we only really care // about the prolog at this point so we don't overrun our buffer - return CERR_CannotReadBitmapFile; + return KmnCompilerMessages::ERROR_CannotReadBitmapFile; } + *FileSize = bufvec.size(); *Buf = new KMX_BYTE[*FileSize]; - if(!loadfileproc(szNameUtf8.c_str(), fk->extra->kmnFilename.c_str(), *Buf, (int*) FileSize, msgprocContext)) { - delete[] *Buf; - return CERR_CannotReadBitmapFile; - } + std::copy(bufvec.begin(), bufvec.end(), *Buf); /* Test for version 7.0 icon support */ if (*((PKMX_CHAR)*Buf) != 'B' && *(((PKMX_CHAR)*Buf) + 1) != 'M') { - VERIFY_KEYBOARD_VERSION(fk, VERSION_70, CERR_70FeatureOnly); + if(!VerifyKeyboardVersion(fk, VERSION_70)) { + return KmnCompilerMessages::ERROR_70FeatureOnly; + } } - return CERR_None; + return STATUS_Success; } int atoiW(PKMX_WCHAR p) @@ -3452,14 +3646,14 @@ KMX_DWORD kmcmp::CheckUTF16(int n) 0xFDE8, 0xFDE9, 0xFDEA, 0xFDEB, 0xFDEC, 0xFDED, 0xFDEE, 0xFDEF, 0xFFFF, 0xFFFE, 0 }; - if (n == 0) return CERR_ReservedCharacter; + if (n == 0) return KmnCompilerMessages::ERROR_ReservedCharacter; for (int i = 0; res[i] > 0; i++) if (n == res[i]) { - AddWarning(CWARN_ReservedCharacter); + ReportCompilerMessage(KmnCompilerMessages::WARN_ReservedCharacter); break; } - return CERR_None; + return STATUS_Success; } KMX_DWORD kmcmp::UTF32ToUTF16(int n, int *n1, int *n2) @@ -3468,25 +3662,30 @@ KMX_DWORD kmcmp::UTF32ToUTF16(int n, int *n1, int *n2) if (n <= 0xFFFF) { *n1 = n; - if (n >= 0xD800 && n <= 0xDFFF) AddWarning(CWARN_UnicodeSurrogateUsed); + if (n >= 0xD800 && n <= 0xDFFF) { + ReportCompilerMessage(KmnCompilerMessages::WARN_UnicodeSurrogateUsed); + } return kmcmp::CheckUTF16(*n1); } - if ((n & 0xFFFF) == 0xFFFF || (n & 0xFFFF) == 0xFFFE) AddWarning(CWARN_ReservedCharacter); - if (n < 0 || n > 0x10FFFF) return CERR_InvalidCharacter; + if ((n & 0xFFFF) == 0xFFFF || (n & 0xFFFF) == 0xFFFE) { + ReportCompilerMessage(KmnCompilerMessages::WARN_ReservedCharacter); + } + if (n < 0 || n > 0x10FFFF) { + return KmnCompilerMessages::ERROR_InvalidCharacter; + } n = n - 0x10000; *n1 = (n / 0x400) + 0xD800; *n2 = (n % 0x400) + 0xDC00; KMX_DWORD msg; - if ((msg = kmcmp::CheckUTF16(*n1)) != CERR_None) return msg; + if ((msg = kmcmp::CheckUTF16(*n1)) != STATUS_Success) return msg; return kmcmp::CheckUTF16(*n2); } -KMX_DWORD BuildVKDictionary(PFILE_KEYBOARD fk) -{ +KMX_BOOL BuildVKDictionary(PFILE_KEYBOARD fk) { KMX_DWORD i; size_t len = 0; - if (fk->cxVKDictionary == 0) return CERR_None; + if (fk->cxVKDictionary == 0) return TRUE; for (i = 0; i < fk->cxVKDictionary; i++) { len += u16len(fk->dpVKDictionary[i].szName) + 1; @@ -3504,9 +3703,12 @@ KMX_DWORD BuildVKDictionary(PFILE_KEYBOARD fk) *p = 0; KMX_DWORD dwStoreID; - KMX_DWORD msg = AddStore(fk, TSS_VKDICTIONARY, storeval, &dwStoreID); + if(!AddStore(fk, TSS_VKDICTIONARY, storeval, &dwStoreID)) { + delete[] storeval; + return FALSE; + } delete[] storeval; - return msg; + return TRUE; } int GetVKCode(PFILE_KEYBOARD fk, PKMX_WCHAR p) @@ -3599,7 +3801,7 @@ bool UTF16TempFromUTF8(KMX_BYTE* infile, int sz, KMX_BYTE** tempfile, int *sz16) std::wstring_convert, char16_t> converter; result = converter.from_bytes((char*)infile, (char*)infile+sz); } catch(std::range_error& e) { - AddCompileError(CHINT_NonUnicodeFile); + ReportCompilerMessage(KmnCompilerMessages::HINT_NonUnicodeFile); result.resize(sz); for(int i = 0; i < sz; i++) { result[i] = CP1252_UNICODE[infile[i]]; diff --git a/developer/src/kmcmplib/src/CompilerErrors.cpp b/developer/src/kmcmplib/src/CompilerErrors.cpp new file mode 100644 index 0000000000..6de261c8e9 --- /dev/null +++ b/developer/src/kmcmplib/src/CompilerErrors.cpp @@ -0,0 +1,31 @@ +#include "pch.h" + +#include +#include +#include + +namespace kmcmp { + int ErrChr; + int nErrors = 0; + kmcmp_CompilerMessageProc msgproc = nullptr; + void* msgprocContext = NULL; + std::string messageFilename; +} + +void ReportCompilerMessage(KMX_DWORD msg, const std::vector& parameters) { + const KMX_DWORD severity = msg & MESSAGE_SEVERITY_MASK; + + if (severity == CompilerErrorSeverity::Error || severity == CompilerErrorSeverity::Fatal) { + kmcmp::nErrors++; + } + + KMCMP_COMPILER_RESULT_MESSAGE message; + message.errorCode = msg; + message.lineNumber = kmcmp::currentLine + 1; + message.columnNumber = kmcmp::ErrChr; + message.parameters = parameters; + message.filename = kmcmp::messageFilename; + (*kmcmp::msgproc)(message, kmcmp::msgprocContext); + + kmcmp::ErrChr = 0; +} diff --git a/developer/src/kmcmplib/src/CompilerErrors.h b/developer/src/kmcmplib/src/CompilerErrors.h new file mode 100644 index 0000000000..ba57784639 --- /dev/null +++ b/developer/src/kmcmplib/src/CompilerErrors.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +namespace kmcmp { + extern kmcmp_CompilerMessageProc msgproc; + extern void* msgprocContext; + extern std::string messageFilename; +} + +void ReportCompilerMessage(KMX_DWORD msg, const std::vector& parameters = {}); diff --git a/developer/src/kmcmplib/src/CompilerInterfaces.cpp b/developer/src/kmcmplib/src/CompilerInterfaces.cpp index 1796859000..11cbd95e59 100644 --- a/developer/src/kmcmplib/src/CompilerInterfaces.cpp +++ b/developer/src/kmcmplib/src/CompilerInterfaces.cpp @@ -25,39 +25,38 @@ EXTERN bool kmcmp_CompileKeyboard( kmcmp::CompileTarget = options.target; if (!messageProc || !loadFileProc || !pszInfile) { - AddCompileError(CERR_BadCallParams); + ReportCompilerMessage(KmnCompilerMessages::FATAL_BadCallParams); return FALSE; } - msgproc = messageProc; - loadfileproc = loadFileProc; - msgprocContext = (void*)procContext; + kmcmp::messageFilename = pszInfile; + kmcmp::msgproc = messageProc; + kmcmp::loadfileproc = loadFileProc; + kmcmp::msgprocContext = (void*)procContext; kmcmp::currentLine = 0; kmcmp::nErrors = 0; int sz; - if(!loadFileProc(pszInfile, "", nullptr, &sz, msgprocContext)) { - AddCompileError(CERR_InfileNotExist); + std::vector bufvec = kmcmp::loadfileproc(pszInfile, ""); + sz = bufvec.size(); + if(!sz) { + ReportCompilerMessage(KmnCompilerMessages::ERROR_InfileNotExist); return FALSE; } if(sz < 3) { // Technically, a 3 byte file can never be a valid .kmn, so we can shortcut // here and avoid testing outside memory bounds for looking at BOM - AddCompileError(CERR_CannotReadInfile); + ReportCompilerMessage(KmnCompilerMessages::ERROR_CannotReadInfile); return FALSE; } KMX_BYTE* infile = new KMX_BYTE[sz+1]; if(!infile) { - AddCompileError(CERR_CannotAllocateMemory); - return FALSE; - } - if(!loadFileProc(pszInfile, "", infile, &sz, msgprocContext)) { - delete[] infile; - AddCompileError(CERR_CannotReadInfile); + ReportCompilerMessage(KmnCompilerMessages::FATAL_CannotAllocateMemory); return FALSE; } + std::copy(bufvec.begin(), bufvec.end(), infile); infile[sz] = 0; // zero-terminate for safety, not technically needed but helps avoid memory bugs int offset = 0; @@ -70,7 +69,7 @@ EXTERN bool kmcmp_CompileKeyboard( int sz16; if(!UTF16TempFromUTF8(infile, sz, &infile16, &sz16)) { delete[] infile; - AddCompileError(CERR_CannotCreateTempfile); + ReportCompilerMessage(KmnCompilerMessages::FATAL_CannotCreateTempfile); return FALSE; } delete[] infile; @@ -96,8 +95,8 @@ EXTERN bool kmcmp_CompileKeyboard( //TODO: FreeKeyboardPointers(fk); - if(msg != CERR_None) { - AddCompileError(msg); + if(msg != STATUS_Success) { + ReportCompilerMessage(msg); return FALSE; } diff --git a/developer/src/kmcmplib/src/CompilerInterfacesWasm.cpp b/developer/src/kmcmplib/src/CompilerInterfacesWasm.cpp index 977b3b7443..a857b41dce 100644 --- a/developer/src/kmcmplib/src/CompilerInterfacesWasm.cpp +++ b/developer/src/kmcmplib/src/CompilerInterfacesWasm.cpp @@ -3,49 +3,20 @@ #ifdef __EMSCRIPTEN__ -/* - WASM interface for compiler message callback -*/ -EM_JS(int, wasm_msgproc, (int line, int msgcode, const char* text, char* context), { - const proc = globalThis[UTF8ToString(context)].message; - if(!proc || typeof proc != 'function') { - console.log(`[${line}: ${msgcode}: ${UTF8ToString(text)}]`); - return 0; - } else { - return proc(line, msgcode, UTF8ToString(text)); +struct WasmCallbackInterface { + virtual void message(const KMCMP_COMPILER_RESULT_MESSAGE& message) = 0; + virtual const std::vector loadFile(const std::string& filename, const std::string& baseFilename) = 0; + virtual ~WasmCallbackInterface() {} +}; + +struct WasmCallbackInterfaceWrapper : public emscripten::wrapper { + EMSCRIPTEN_WRAPPER(WasmCallbackInterfaceWrapper); + void message(const KMCMP_COMPILER_RESULT_MESSAGE& message) { + return call("message", message); } -}); - -EM_JS(int, wasm_loadfileproc, (const char* filename, const char* baseFilename, void* buffer, int bufferSize, char* context), { - const proc = globalThis[UTF8ToString(context)].loadFile; - if(!proc || typeof proc != 'function') { - return 0; - } else { - if(buffer == 0) { - return proc(UTF8ToString(filename), UTF8ToString(baseFilename), 0, 0); - } else { - return proc(UTF8ToString(filename), UTF8ToString(baseFilename), buffer, bufferSize); - } + const std::vector loadFile(const std::string& filename, const std::string& baseFilename) { + return call>("loadFile", filename, baseFilename); } -}); - -bool wasm_LoadFileProc(const char* filename, const char* baseFilename, void* buffer, int* bufferSize, void* context) { - char* msgProc = static_cast(context); - if(buffer == nullptr) { - *bufferSize = wasm_loadfileproc(filename, baseFilename, 0, 0, msgProc); - return *bufferSize != -1; - } else { - return wasm_loadfileproc(filename, baseFilename, buffer, *bufferSize, msgProc) == 1; - } -} - -int wasm_CompilerMessageProc(int line, uint32_t dwMsgCode, const char* szText, void* context) { - char* msgProc = static_cast(context); - return wasm_msgproc(line, dwMsgCode, szText, msgProc); -} - -struct WASM_COMPILER_INTERFACE { - std::string callbacksKey; // key of callbacks object on globalThis }; struct WASM_COMPILER_RESULT { @@ -56,16 +27,28 @@ struct WASM_COMPILER_RESULT { KMCMP_COMPILER_RESULT_EXTRA extra; }; -WASM_COMPILER_RESULT kmcmp_wasm_compile(std::string pszInfile, const KMCMP_COMPILER_OPTIONS options, const WASM_COMPILER_INTERFACE intf) { +WasmCallbackInterface* globalCallbacks = nullptr; + +const std::vector wasm_LoadFileProc(const std::string& filename, const std::string& baseFilename) { + return globalCallbacks->loadFile(filename, baseFilename); +} + +void wasm_CompilerMessageProc(const KMCMP_COMPILER_RESULT_MESSAGE& message, void* context) { + globalCallbacks->message(message); +} + +WASM_COMPILER_RESULT kmcmp_wasm_compile(std::string pszInfile, const KMCMP_COMPILER_OPTIONS options, WasmCallbackInterface& callbacks) { WASM_COMPILER_RESULT r = {false}; KMCMP_COMPILER_RESULT kr; + globalCallbacks = &callbacks; + r.result = kmcmp_CompileKeyboard( pszInfile.c_str(), options, wasm_CompilerMessageProc, wasm_LoadFileProc, - intf.callbacksKey.c_str(), + "", //TODO: eliminate? kr ); @@ -76,6 +59,8 @@ WASM_COMPILER_RESULT kmcmp_wasm_compile(std::string pszInfile, const KMCMP_COMPI r.extra = kr.extra; } + globalCallbacks = nullptr; + return r; } @@ -119,6 +104,12 @@ int kmcmp_testSentry() { EMSCRIPTEN_BINDINGS(compiler_interface) { + emscripten::class_("WasmCallbackInterface") + .function("message", &WasmCallbackInterface::message, emscripten::pure_virtual()) + .function("loadFile", &WasmCallbackInterface::loadFile, emscripten::pure_virtual()) + .allow_subclass("WasmCallbackInterfaceWrapper") + ; + emscripten::class_("CompilerOptions") .constructor<>() .property("saveDebug", &KMCMP_COMPILER_OPTIONS::saveDebug) @@ -128,11 +119,6 @@ EMSCRIPTEN_BINDINGS(compiler_interface) { .property("target", &KMCMP_COMPILER_OPTIONS::target) ; - emscripten::class_("CompilerInterface") - .constructor<>() - .property("callbacksKey", &WASM_COMPILER_INTERFACE::callbacksKey) - ; - emscripten::class_("CompilerResult") .constructor<>() .property("result", &WASM_COMPILER_RESULT::result) @@ -141,6 +127,15 @@ EMSCRIPTEN_BINDINGS(compiler_interface) { .property("extra", &WASM_COMPILER_RESULT::extra) ; + emscripten::class_("CompilerResultMessage") + .constructor<>() + .property("errorCode", &KMCMP_COMPILER_RESULT_MESSAGE::errorCode) + .property("lineNumber", &KMCMP_COMPILER_RESULT_MESSAGE::lineNumber) + .property("columnNumber", &KMCMP_COMPILER_RESULT_MESSAGE::columnNumber) + .property("filename", &KMCMP_COMPILER_RESULT_MESSAGE::filename) + .property("parameters", &KMCMP_COMPILER_RESULT_MESSAGE::parameters) + ; + emscripten::class_("CompilerResultExtra") .constructor<>() .property("targets", &KMCMP_COMPILER_RESULT_EXTRA::targets) diff --git a/developer/src/kmcmplib/src/DeprecationChecks.cpp b/developer/src/kmcmplib/src/DeprecationChecks.cpp index 11042f0c13..671f3ec9a4 100644 --- a/developer/src/kmcmplib/src/DeprecationChecks.cpp +++ b/developer/src/kmcmplib/src/DeprecationChecks.cpp @@ -6,15 +6,14 @@ #include "kmcmplib.h" #include "DeprecationChecks.h" -KMX_BOOL kmcmp::WarnDeprecatedHeader() { // I4866 -if( AWarnDeprecatedCode_GLOBAL_LIB){ - AddWarningBool(CWARN_HeaderStatementIsDeprecated); +void kmcmp::WarnDeprecatedHeader() { // I4866 + if (AWarnDeprecatedCode_GLOBAL_LIB) { + ReportCompilerMessage(KmnCompilerMessages::WARN_HeaderStatementIsDeprecated); } - return TRUE; } /* Flag presence of deprecated features */ -KMX_BOOL kmcmp::CheckForDeprecatedFeatures(PFILE_KEYBOARD fk) { +void kmcmp::CheckForDeprecatedFeatures(PFILE_KEYBOARD fk) { /* For Keyman 10, we deprecated: // < Keyman 7 @@ -31,7 +30,7 @@ KMX_BOOL kmcmp::CheckForDeprecatedFeatures(PFILE_KEYBOARD fk) { PFILE_STORE sp; if (!AWarnDeprecatedCode_GLOBAL_LIB) { - return TRUE; + return; } if (fk->version >= VERSION_100) { @@ -42,12 +41,10 @@ KMX_BOOL kmcmp::CheckForDeprecatedFeatures(PFILE_KEYBOARD fk) { sp->dwSystemID == TSS_ETHNOLOGUECODE || sp->dwSystemID == TSS_WINDOWSLANGUAGES) { kmcmp::currentLine = sp->line; - AddWarningBool(CWARN_LanguageHeadersDeprecatedInKeyman10); + ReportCompilerMessage(KmnCompilerMessages::WARN_LanguageHeadersDeprecatedInKeyman10); } } } kmcmp::currentLine = oldCurrentLine; - - return TRUE; } diff --git a/developer/src/kmcmplib/src/DeprecationChecks.h b/developer/src/kmcmplib/src/DeprecationChecks.h index 941b87f1a4..329519ec32 100644 --- a/developer/src/kmcmplib/src/DeprecationChecks.h +++ b/developer/src/kmcmplib/src/DeprecationChecks.h @@ -4,6 +4,6 @@ #include "kmcmplib.h" namespace kmcmp{ -KMX_BOOL WarnDeprecatedHeader(); -KMX_BOOL CheckForDeprecatedFeatures(PFILE_KEYBOARD fk); + void WarnDeprecatedHeader(); + void CheckForDeprecatedFeatures(PFILE_KEYBOARD fk); } diff --git a/developer/src/kmcmplib/src/NamedCodeConstants.cpp b/developer/src/kmcmplib/src/NamedCodeConstants.cpp index 6067a1ae50..40e47d7a00 100644 --- a/developer/src/kmcmplib/src/NamedCodeConstants.cpp +++ b/developer/src/kmcmplib/src/NamedCodeConstants.cpp @@ -120,15 +120,14 @@ KMX_BOOL NamedCodeConstants::LoadFile(PFILE_KEYBOARD fk, const KMX_WCHAR *filena int FileSize; KMX_BYTE* Buf; - if(!loadfileproc(szNameUtf8.c_str(), fk->extra->kmnFilename.c_str(), nullptr, &FileSize, msgprocContext)) { + std::vector bufvec = loadfileproc(szNameUtf8, fk->extra->kmnFilename); + FileSize = bufvec.size(); + if(!FileSize) { return FALSE; } Buf = new KMX_BYTE[FileSize+1]; - if(!loadfileproc(szNameUtf8.c_str(), fk->extra->kmnFilename.c_str(), Buf, &FileSize, msgprocContext)) { - delete[] Buf; - return FALSE; - } + std::copy(bufvec.begin(), bufvec.end(), Buf); Buf[FileSize] = 0; // zero-terminate for strtok char* filetok; diff --git a/developer/src/kmcmplib/src/UnreachableRules.cpp b/developer/src/kmcmplib/src/UnreachableRules.cpp index 9d114a80a4..c84bdfb1f5 100644 --- a/developer/src/kmcmplib/src/UnreachableRules.cpp +++ b/developer/src/kmcmplib/src/UnreachableRules.cpp @@ -25,7 +25,8 @@ namespace kmcmp { } } -KMX_DWORD VerifyUnreachableRules(PFILE_GROUP gp) { + +void VerifyUnreachableRules(PFILE_GROUP gp) { PFILE_KEY kp = gp->dpKeyArray; KMX_DWORD i; @@ -41,8 +42,9 @@ KMX_DWORD VerifyUnreachableRules(PFILE_GROUP gp) { if (kp->Line != k1.Line && reportedLines.count(kp->Line) == 0) { reportedLines.insert(kp->Line); kmcmp::currentLine = kp->Line; - snprintf(ErrExtraLIB, ERR_EXTRA_LIB_LEN, " Overridden by rule on line %d", k1.Line); - AddWarning(CHINT_UnreachableRule); + ReportCompilerMessage(KmnCompilerMessages::HINT_UnreachableRule, { + /* LineNumber */ std::to_string(k1.Line) + }); } } else { @@ -51,6 +53,4 @@ KMX_DWORD VerifyUnreachableRules(PFILE_GROUP gp) { } kmcmp::currentLine = oldCurrentLine; - - return CERR_None; } diff --git a/developer/src/kmcmplib/src/UnreachableRules.h b/developer/src/kmcmplib/src/UnreachableRules.h index d9eac65ce3..a7ccba3466 100644 --- a/developer/src/kmcmplib/src/UnreachableRules.h +++ b/developer/src/kmcmplib/src/UnreachableRules.h @@ -1,3 +1,3 @@ #pragma once -KMX_DWORD VerifyUnreachableRules(PFILE_GROUP gp); +void VerifyUnreachableRules(PFILE_GROUP gp); diff --git a/developer/src/kmcmplib/src/compfile.h b/developer/src/kmcmplib/src/compfile.h index f45cb3ea34..e32b2c2631 100644 --- a/developer/src/kmcmplib/src/compfile.h +++ b/developer/src/kmcmplib/src/compfile.h @@ -31,7 +31,6 @@ #define SZMAX_STORENAME 80 #define SZMAX_GROUPNAME 80 #define SZMAX_DEADKEYNAME 80 -#define SZMAX_ERRORTEXT 512 #define SZMAX_VKDICTIONARYNAME 80 #define MAX_WARNINGS 100 @@ -167,26 +166,4 @@ const KMX_DWORD sz_FILE_DEADKEY = sizeof(FILE_DEADKEY); const KMX_DWORD sz_FILE_VKDICTIONARY = sizeof(FILE_VKDICTIONARY); const KMX_DWORD sz_FILE_KEYBOARD = sizeof(FILE_KEYBOARD); -struct COMPMSG { - KMX_CHAR szText[SZMAX_ERRORTEXT]; - KMX_DWORD Line; - KMX_DWORD dwMsgCode; -}; - -typedef COMPMSG *PCOMPMSG; - -struct COMPILEMESSAGES { - int nMessages; - int nErrors; - - PCOMPMSG cm; - - KMX_DWORD fatalCode; - KMX_CHAR szFatalText[SZMAX_ERRORTEXT]; - - KMX_DWORD currentLine; -}; - -typedef COMPILEMESSAGES *PCOMPILEMESSAGES; - #endif // _COMPFILE_H diff --git a/developer/src/kmcmplib/src/kmcmplib.h b/developer/src/kmcmplib/src/kmcmplib.h index 0d7c4f9004..91edfe1b26 100644 --- a/developer/src/kmcmplib/src/kmcmplib.h +++ b/developer/src/kmcmplib/src/kmcmplib.h @@ -3,9 +3,9 @@ #include #include "compfile.h" #include "NamedCodeConstants.h" +#include namespace kmcmp { - KMX_BOOL AddCompileWarning(char* buf); extern int currentLine; extern KMX_BOOL FShouldAddCompilerVersion; extern KMX_BOOL FSaveDebug, FCompilerWarningsAsErrors; // I4865 // I4866 @@ -17,34 +17,24 @@ namespace kmcmp { extern int BeginLine[4]; extern int currentLine; extern NamedCodeConstants *CodeConstants; + extern kmcmp_LoadFileProc loadfileproc; void RecordDeadkeyNames(PFILE_KEYBOARD fk); - KMX_DWORD AddCompilerVersionStore(PFILE_KEYBOARD fk); + KMX_BOOL AddCompilerVersionStore(PFILE_KEYBOARD fk); } -extern kmcmp_CompilerMessageProc msgproc; -extern kmcmp_LoadFileProc loadfileproc; -extern void* msgprocContext; extern KMX_BOOL AWarnDeprecatedCode_GLOBAL_LIB; -#define ERR_EXTRA_LIB_LEN 256 -extern char ErrExtraLIB[ERR_EXTRA_LIB_LEN]; -KMX_BOOL AddCompileError(KMX_DWORD msg); - -/// Use AddWarningBool for functions that return bool or KMX_BOOL -#define AddWarningBool(warn) { if(AddCompileError(warn)) return FALSE; } -/// Use AddWarning for functions that return KMX_DWORD -#define AddWarning(warn) { if(AddCompileError(warn)) return CERR_Break; } PKMX_WCHAR strtowstr(PKMX_STR in); PFILE_STORE FindSystemStore(PFILE_KEYBOARD fk, KMX_DWORD dwSystemID); bool UTF16TempFromUTF8(KMX_BYTE* infile, int sz, KMX_BYTE** tempfile, int *sz16); KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataSize); -KMX_DWORD AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, KMX_DWORD *dwStoreID= NULL); +KMX_BOOL AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, KMX_DWORD *dwStoreID= NULL); KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess); -KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str); -KMX_DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); -KMX_DWORD ProcessGroupFinish(PFILE_KEYBOARD fk); -KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); +KMX_BOOL ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str); +KMX_BOOL ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); +KMX_BOOL ProcessGroupFinish(PFILE_KEYBOARD fk); +KMX_BOOL ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); int LineTokenType(PKMX_WCHAR *str); -KMX_DWORD BuildVKDictionary(PFILE_KEYBOARD fk); // I3438 +KMX_BOOL BuildVKDictionary(PFILE_KEYBOARD fk); // I3438 diff --git a/developer/src/kmcmplib/src/meson.build b/developer/src/kmcmplib/src/meson.build index 16af213dc3..2b9a431e09 100644 --- a/developer/src/kmcmplib/src/meson.build +++ b/developer/src/kmcmplib/src/meson.build @@ -72,9 +72,9 @@ lib = library('kmcmplib', 'CheckNCapsConsistency.cpp', 'CompileKeyboardBuffer.cpp', 'Compiler.cpp', + 'CompilerErrors.cpp', 'CompilerInterfaces.cpp', 'CompilerInterfacesWasm.cpp', - 'CompMsg.cpp', 'cp1252.cpp', 'DeprecationChecks.cpp', 'Edition.cpp', diff --git a/developer/src/kmcmplib/src/versioning.cpp b/developer/src/kmcmplib/src/versioning.cpp index 4c2f04e1e9..87c7d0070b 100644 --- a/developer/src/kmcmplib/src/versioning.cpp +++ b/developer/src/kmcmplib/src/versioning.cpp @@ -5,8 +5,6 @@ #include "versioning.h" KMX_BOOL kmcmp::CheckKeyboardFinalVersion(PFILE_KEYBOARD fk) { - KMX_CHAR buf[128]; - if (fk->dwFlags & KF_AUTOMATICVERSION) { if (fk->version <= 0) { fk->version = VERSION_60; // minimum version that we can be safe with @@ -15,8 +13,10 @@ KMX_BOOL kmcmp::CheckKeyboardFinalVersion(PFILE_KEYBOARD fk) { if(kmcmp::CompileTarget != CKF_KEYMANWEB) { // Note: the KeymanWeb compiler is responsible for reporting minimum // version for the web targets - snprintf(buf, 128, "The compiler has assigned a minimum engine version of %d.%d based on features used in this keyboard", (int)((fk->version & 0xFF00) >> 8), (int)(fk->version & 0xFF)); - AddCompileWarning(buf); + ReportCompilerMessage(KmnCompilerMessages::INFO_MinimumCoreEngineVersion, { + /* majorVersion */ std::to_string((fk->version & 0xFF00) >> 8), + /* minorVersion */ std::to_string(fk->version & 0xFF) + }); } } diff --git a/developer/src/kmcmplib/src/versioning.h b/developer/src/kmcmplib/src/versioning.h index a3a1c597bf..a172b45b2d 100644 --- a/developer/src/kmcmplib/src/versioning.h +++ b/developer/src/kmcmplib/src/versioning.h @@ -3,11 +3,6 @@ #include "compfile.h" #include "../../../../common/include/km_types.h" -#define VERIFY_KEYBOARD_VERSION(fk, ver, err) { \ - if(!VerifyKeyboardVersion((fk), (ver))) \ - return (err); \ -} - namespace kmcmp { KMX_BOOL CheckKeyboardFinalVersion(PFILE_KEYBOARD fk); } diff --git a/developer/src/kmcmplib/tests/api-test.cpp b/developer/src/kmcmplib/tests/api-test.cpp index fc430e8cdb..52769f2b04 100644 --- a/developer/src/kmcmplib/tests/api-test.cpp +++ b/developer/src/kmcmplib/tests/api-test.cpp @@ -34,6 +34,7 @@ int main(int argc, char *argv[]) { setup(); test_kmcmp_CompileKeyboard(argv[1]); + setup(); test_GetCompileTargetsFromTargetsStore(); return 0; @@ -65,35 +66,72 @@ void test_kmcmp_CompileKeyboard(char *kmn_file) { options.target = CKF_KEYMAN; assert(!kmcmp_CompileKeyboard(kmn_file, options, msgproc, loadfileProc, nullptr, result)); assert(error_vec.size() == 1); - assert(error_vec[0] == CERR_CannotReadInfile); + assert(error_vec[0] == KmnCompilerMessages::ERROR_InfileNotExist); // zero byte no longer gives us KmnCompilerMessages::ERROR_CannotReadInfile unlink(kmn_file); } -extern KMX_DWORD GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets); +extern KMX_BOOL GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store, int &targets); void test_GetCompileTargetsFromTargetsStore() { int targets = 0; - assert(GetCompileTargetsFromTargetsStore(u"any", targets) == CERR_None); + + setup(); + assert(GetCompileTargetsFromTargetsStore(u"any", targets)); + assert(error_vec.size() == 0); assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); - assert(GetCompileTargetsFromTargetsStore(u"windows", targets) == CERR_None); + + setup(); + assert(GetCompileTargetsFromTargetsStore(u"windows", targets)); + assert(error_vec.size() == 0); assert(targets == COMPILETARGETS_KMX); - assert(GetCompileTargetsFromTargetsStore(u"desktop", targets) == CERR_None); + + setup(); + assert(GetCompileTargetsFromTargetsStore(u"desktop", targets)); + assert(error_vec.size() == 0); assert(targets == COMPILETARGETS_KMX); - assert(GetCompileTargetsFromTargetsStore(u"mobile", targets) == CERR_None); + + setup(); + assert(GetCompileTargetsFromTargetsStore(u"mobile", targets)); + assert(error_vec.size() == 0); assert(targets == COMPILETARGETS_JS); - assert(GetCompileTargetsFromTargetsStore(u"web", targets) == CERR_None); + + setup(); + assert(GetCompileTargetsFromTargetsStore(u"web", targets)); + assert(error_vec.size() == 0); assert(targets == COMPILETARGETS_JS); - assert(GetCompileTargetsFromTargetsStore(u"desktop mobile", targets) == CERR_None); + + setup(); + assert(GetCompileTargetsFromTargetsStore(u"desktop mobile", targets)); + assert(error_vec.size() == 0); assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); - assert(GetCompileTargetsFromTargetsStore(u"desktop tablet", targets) == CERR_None); + + setup(); + assert(GetCompileTargetsFromTargetsStore(u"desktop tablet", targets)); + assert(error_vec.size() == 0); assert(targets == (COMPILETARGETS_KMX | COMPILETARGETS_JS)); - assert(GetCompileTargetsFromTargetsStore(u"foo bar baz", targets) == CERR_InvalidTarget); + + setup(); + assert(!GetCompileTargetsFromTargetsStore(u"foo bar baz", targets)); + assert(error_vec.size() == 1); + assert(error_vec[0] == KmnCompilerMessages::ERROR_InvalidTarget); assert(targets == 0); - assert(GetCompileTargetsFromTargetsStore(u"windows chromeos", targets) == CERR_InvalidTarget); + + setup(); + assert(!GetCompileTargetsFromTargetsStore(u"windows chromeos", targets)); + assert(error_vec.size() == 1); + assert(error_vec[0] == KmnCompilerMessages::ERROR_InvalidTarget); assert(targets == 0); - assert(GetCompileTargetsFromTargetsStore(u" ", targets) == CERR_NoTargetsSpecified); + + setup(); + assert(!GetCompileTargetsFromTargetsStore(u" ", targets)); + assert(error_vec.size() == 1); + assert(error_vec[0] == KmnCompilerMessages::ERROR_NoTargetsSpecified); assert(targets == 0); - assert(GetCompileTargetsFromTargetsStore(u"", targets) == CERR_NoTargetsSpecified); + + setup(); + assert(!GetCompileTargetsFromTargetsStore(u"", targets)); + assert(error_vec.size() == 1); + assert(error_vec[0] == KmnCompilerMessages::ERROR_NoTargetsSpecified); assert(targets == 0); } diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index 58dfc0e593..22b38dccc6 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -3,15 +3,14 @@ #include "../include/kmcmplibapi.h" #include "../src/kmx_u16.h" #include "../src/compfile.h" -#include "../src/CompMsg.h" +#include "../src/CompilerErrors.h" #include "../../common/include/kmn_compiler_errors.h" #include "../../../../common/include/km_types.h" #include "../../../../common/include/kmx_file.h" PKMX_WCHAR strtowstr(PKMX_STR in); PKMX_STR wstrtostr(PKMX_WCHAR in); -KMX_BOOL AddCompileError(KMX_DWORD msg); -KMX_DWORD ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); +KMX_BOOL ProcessBeginLine(PFILE_KEYBOARD fk, PKMX_WCHAR p); KMX_DWORD ValidateMatchNomatchOutput(PKMX_WCHAR p); KMX_BOOL IsValidKeyboardVersion(KMX_WCHAR *dpString); PKMX_WCHAR GetDelimitedString(PKMX_WCHAR *p, KMX_WCHAR const * Delimiters, KMX_WORD Flags); @@ -25,19 +24,13 @@ bool isIntegerWstring(PKMX_WCHAR p); bool hasPreamble(std::u16string result); KMX_DWORD ProcessKeyLineImpl(PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX_BOOL IsUnicode, PKMX_WCHAR pklIn, PKMX_WCHAR pklKey, PKMX_WCHAR pklOut); -extern kmcmp_CompilerMessageProc msgproc; - namespace kmcmp { extern int nErrors; extern int ErrChr; extern int BeginLine[4]; extern int CompileTarget; - KMX_BOOL AddCompileWarning(char* buf); } -#define ERR_EXTRA_LIB_LEN 256 -extern char ErrExtraLIB[ERR_EXTRA_LIB_LEN]; - class CompilerTest : public testing::Test { protected: FILE_KEYBOARD fileKeyboard; @@ -53,11 +46,10 @@ class CompilerTest : public testing::Test { } void initGlobals() { - msgproc = NULL; - szText_stub[0] = '\0'; + kmcmp::msgproc = msgproc_collect; + msgproc_errors.clear(); kmcmp::nErrors = 0; kmcmp::ErrChr = 0; - ErrExtraLIB[0] = '\0'; kmcmp::BeginLine[BEGIN_ANSI] = -1; kmcmp::BeginLine[BEGIN_UNICODE] = -1; kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; @@ -115,21 +107,14 @@ class CompilerTest : public testing::Test { } public: - static KMX_CHAR szText_stub[]; + static std::vector msgproc_errors; - static int msgproc_true_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { - strcpy(szText_stub, szText); - return 1; - }; - - static int msgproc_false_stub(int line, uint32_t dwMsgCode, const char* szText, void* context) { - strcpy(szText_stub, szText); - return 0; - }; + static void msgproc_collect(const KMCMP_COMPILER_RESULT_MESSAGE &message, void* context) { + msgproc_errors.push_back(message); + } }; -#define COMPILE_ERROR_MAX_LEN (SZMAX_ERRORTEXT + 1 + 280) -KMX_CHAR CompilerTest::szText_stub[COMPILE_ERROR_MAX_LEN]; +std::vector CompilerTest::msgproc_errors; TEST_F(CompilerTest, strtowstr_test) { EXPECT_EQ(0, u16cmp(u"hello", strtowstr((PKMX_STR)"hello"))); @@ -141,129 +126,120 @@ TEST_F(CompilerTest, wstrtostr_test) { EXPECT_EQ(0, strcmp("", wstrtostr((PKMX_WCHAR)u""))); }; -TEST_F(CompilerTest, AddCompileWarning_test) { - msgproc = msgproc_false_stub; - const char *const WARNING_TEXT = "warning"; - EXPECT_EQ(0, kmcmp::nErrors); - EXPECT_FALSE(kmcmp::AddCompileWarning((PKMX_CHAR)WARNING_TEXT)); - EXPECT_EQ(0, strcmp(WARNING_TEXT, szText_stub)); - EXPECT_EQ(0, kmcmp::nErrors); -}; +// TEST_F(CompilerTest, ReportCompilerMessage_test) { +// msgproc = msgproc_true_stub; +// kmcmp::ErrChr = 0; -TEST_F(CompilerTest, AddCompileError_test) { - msgproc = msgproc_true_stub; - kmcmp::ErrChr = 0; - ErrExtraLIB[0] = '\0'; - KMX_CHAR expected[COMPILE_ERROR_MAX_LEN]; +// // SevFatal +// EXPECT_EQ(0, kmcmp::nErrors); +// EXPECT_EQ(SevFatal, KmnCompilerMessages::FATAL_CannotCreateTempfile & SevFatal); +// EXPECT_TRUE(ReportCompilerMessage(KmnCompilerMessages::FATAL_CannotCreateTempfile)); +// EXPECT_EQ(1, kmcmp::nErrors); - // CERR_FATAL - EXPECT_EQ(0, kmcmp::nErrors); - EXPECT_EQ(CERR_FATAL, CERR_CannotCreateTempfile & CERR_FATAL); - EXPECT_TRUE(AddCompileError(CERR_CannotCreateTempfile)); - EXPECT_EQ(0, strcmp(GetCompilerErrorString(CERR_CannotCreateTempfile), szText_stub)); - EXPECT_EQ(1, kmcmp::nErrors); +// // SevError +// EXPECT_EQ(SevError, KmnCompilerMessages::ERROR_InvalidLayoutLine & SevError); +// EXPECT_FALSE(ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLayoutLine)); +// EXPECT_EQ(2, kmcmp::nErrors); - // CERR_ERROR - EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); - EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp(GetCompilerErrorString(CERR_InvalidLayoutLine), szText_stub)); - EXPECT_EQ(2, kmcmp::nErrors); +// // Unknown +// const KMX_DWORD UNKNOWN_ERROR = 0x00004FFF; // top of range ERROR +// EXPECT_EQ(SevError, UNKNOWN_ERROR & SevError); +// EXPECT_FALSE(ReportCompilerMessage(UNKNOWN_ERROR)); +// sprintf(expected, "Unknown error %x", UNKNOWN_ERROR); +// EXPECT_EQ(3, kmcmp::nErrors); - // Unknown - const KMX_DWORD UNKNOWN_ERROR = 0x00004FFF; // top of range ERROR - EXPECT_EQ(CERR_ERROR, UNKNOWN_ERROR & CERR_ERROR); - EXPECT_FALSE(AddCompileError(UNKNOWN_ERROR)); - sprintf(expected, "Unknown error %x", UNKNOWN_ERROR); - EXPECT_EQ(0, strcmp(expected, szText_stub)); - EXPECT_EQ(3, kmcmp::nErrors); +// // ErrChr +// const int ERROR_CHAR_INDEX = 42; +// kmcmp::ErrChr = ERROR_CHAR_INDEX ; +// EXPECT_EQ(SevError, KmnCompilerMessages::ERROR_InvalidLayoutLine & SevError); +// EXPECT_FALSE(ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLayoutLine)); +// kmcmp::ErrChr = 0; +// EXPECT_EQ(4, kmcmp::nErrors); - // ErrChr - const int ERROR_CHAR_INDEX = 42; - kmcmp::ErrChr = ERROR_CHAR_INDEX ; - EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); - EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - sprintf(expected, "%s character offset: %d", GetCompilerErrorString(CERR_InvalidLayoutLine), ERROR_CHAR_INDEX); - EXPECT_EQ(0, strcmp(expected, szText_stub)); - kmcmp::ErrChr = 0; - EXPECT_EQ(4, kmcmp::nErrors); - - // ErrExtraLIB - const char *const EXTRA_LIB_TEXT = " extra lib"; - strcpy(ErrExtraLIB, EXTRA_LIB_TEXT); - EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); - EXPECT_FALSE(AddCompileError(CERR_InvalidLayoutLine)); - sprintf(expected, "%s%s", GetCompilerErrorString(CERR_InvalidLayoutLine), EXTRA_LIB_TEXT); - EXPECT_EQ(0, strcmp(expected, szText_stub)); - ErrExtraLIB[0] = '\0'; - EXPECT_EQ(5, kmcmp::nErrors); - - // msgproc returns FALSE - msgproc = msgproc_false_stub; - EXPECT_EQ(CERR_ERROR, CERR_InvalidLayoutLine & CERR_ERROR); - EXPECT_TRUE(AddCompileError(CERR_InvalidLayoutLine)); - EXPECT_EQ(0, strcmp(GetCompilerErrorString(CERR_InvalidLayoutLine), szText_stub)); - EXPECT_EQ(6, kmcmp::nErrors); -}; +// // msgproc returns FALSE +// msgproc = msgproc_false_stub; +// EXPECT_EQ(SevError, KmnCompilerMessages::ERROR_InvalidLayoutLine & SevError); +// EXPECT_TRUE(ReportCompilerMessage(KmnCompilerMessages::ERROR_InvalidLayoutLine)); +// EXPECT_EQ(6, kmcmp::nErrors); +// }; TEST_F(CompilerTest, ProcessBeginLine_test) { KMX_WCHAR str[LINESIZE]; - // CERR_NoTokensFound + // KmnCompilerMessages::ERROR_NoTokensFound + msgproc_errors.clear(); u16cpy(str, u""); - EXPECT_EQ(CERR_NoTokensFound, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(FALSE, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(1, msgproc_errors.size()); + EXPECT_EQ(KmnCompilerMessages::ERROR_NoTokensFound, msgproc_errors[0].errorCode); - // CERR_InvalidToken + // KmnCompilerMessages::ERROR_InvalidToken + msgproc_errors.clear(); u16cpy(str, u"abc >"); - EXPECT_EQ(CERR_InvalidToken, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(FALSE, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(1, msgproc_errors.size()); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, msgproc_errors[0].errorCode); - // CERR_RepeatedBegin, BEGIN_UNICODE + // KmnCompilerMessages::ERROR_RepeatedBegin, BEGIN_UNICODE + msgproc_errors.clear(); kmcmp::BeginLine[BEGIN_UNICODE] = 0; // not -1 u16cpy(str, u" unicode>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(FALSE, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(1, msgproc_errors.size()); + EXPECT_EQ(KmnCompilerMessages::ERROR_RepeatedBegin, msgproc_errors[0].errorCode); kmcmp::BeginLine[BEGIN_UNICODE] = -1; - // CERR_RepeatedBegin, BEGIN_ANSI + // KmnCompilerMessages::ERROR_RepeatedBegin, BEGIN_ANSI + msgproc_errors.clear(); kmcmp::BeginLine[BEGIN_ANSI] = 0; // not -1 u16cpy(str, u" ansi>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(FALSE, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(1, msgproc_errors.size()); + EXPECT_EQ(KmnCompilerMessages::ERROR_RepeatedBegin, msgproc_errors[0].errorCode); kmcmp::BeginLine[BEGIN_ANSI] = -1; - // CERR_RepeatedBegin, BEGIN_NEWCONTEXT + // KmnCompilerMessages::ERROR_RepeatedBegin, BEGIN_NEWCONTEXT + msgproc_errors.clear(); kmcmp::BeginLine[BEGIN_NEWCONTEXT] = 0; // not -1 u16cpy(str, u" newContext>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(FALSE, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(1, msgproc_errors.size()); + EXPECT_EQ(KmnCompilerMessages::ERROR_RepeatedBegin, msgproc_errors[0].errorCode); kmcmp::BeginLine[BEGIN_NEWCONTEXT] = -1; - // CERR_RepeatedBegin, BEGIN_POSTKEYSTROKE + // KmnCompilerMessages::ERROR_RepeatedBegin, BEGIN_POSTKEYSTROKE + msgproc_errors.clear(); kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = 0; // not -1 u16cpy(str, u" postKeystroke>"); - EXPECT_EQ(CERR_RepeatedBegin, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(FALSE, ProcessBeginLine(&fileKeyboard, str)); + EXPECT_EQ(1, msgproc_errors.size()); + EXPECT_EQ(KmnCompilerMessages::ERROR_RepeatedBegin, msgproc_errors[0].errorCode); kmcmp::BeginLine[BEGIN_POSTKEYSTROKE] = -1; }; TEST_F(CompilerTest, ValidateMatchNomatchOutput_test) { - EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput(NULL)); - EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput((PKMX_WCHAR)u"")); + EXPECT_EQ(STATUS_Success, ValidateMatchNomatchOutput(NULL)); + EXPECT_EQ(STATUS_Success, ValidateMatchNomatchOutput((PKMX_WCHAR)u"")); const KMX_WCHAR context[] = { 'a', 'b', 'c', UC_SENTINEL, CODE_CONTEXT, 'd', 'e', 'f', 0 }; - EXPECT_EQ(CERR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)context)); + EXPECT_EQ(KmnCompilerMessages::ERROR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)context)); const KMX_WCHAR contextex[] = { 'a', 'b', 'c', UC_SENTINEL, CODE_CONTEXTEX, 'd', 'e', 'f', 0 }; - EXPECT_EQ(CERR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)contextex)); + EXPECT_EQ(KmnCompilerMessages::ERROR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)contextex)); const KMX_WCHAR index[] = { 'a', 'b', 'c', UC_SENTINEL, CODE_INDEX, 'd', 'e', 'f', 0 }; - EXPECT_EQ(CERR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)index)); + EXPECT_EQ(KmnCompilerMessages::ERROR_ContextAndIndexInvalidInMatchNomatch, ValidateMatchNomatchOutput((PKMX_WCHAR)index)); const KMX_WCHAR sentinel[] = { 'a', 'b', 'c', UC_SENTINEL, 'd', 'e', 'f', 0 }; - EXPECT_EQ(CERR_None, ValidateMatchNomatchOutput((PKMX_WCHAR)sentinel)); + EXPECT_EQ(STATUS_Success, ValidateMatchNomatchOutput((PKMX_WCHAR)sentinel)); }; -// KMX_DWORD ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) -// KMX_DWORD ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +// KMX_BOOL ParseLine(PFILE_KEYBOARD fk, PKMX_WCHAR str) +// KMX_BOOL ProcessGroupLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) // int kmcmp::cmpkeys(const void *key, const void *elem) -// KMX_DWORD ProcessGroupFinish(PFILE_KEYBOARD fk) -// KMX_DWORD ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) +// KMX_BOOL ProcessGroupFinish(PFILE_KEYBOARD fk) +// KMX_BOOL ProcessStoreLine(PFILE_KEYBOARD fk, PKMX_WCHAR p) // bool resizeStoreArray(PFILE_KEYBOARD fk) // bool resizeKeyArray(PFILE_GROUP gp, int increment) -// KMX_DWORD AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, KMX_DWORD *dwStoreID) +// KMX_BOOL AddStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, const KMX_WCHAR * str, KMX_DWORD *dwStoreID) // KMX_DWORD AddDebugStore(PFILE_KEYBOARD fk, KMX_WCHAR const * str) -// KMX_DWORD ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp) +// KMX_BOOL ProcessSystemStore(PFILE_KEYBOARD fk, KMX_DWORD SystemID, PFILE_STORE sp) // int GetCompileTargetsFromTargetsStore(const KMX_WCHAR* store) TEST_F(CompilerTest, IsValidKeyboardVersion_test) { @@ -281,7 +257,7 @@ TEST_F(CompilerTest, IsValidKeyboardVersion_test) { // KMX_DWORD kmcmp::AddCompilerVersionStore(PFILE_KEYBOARD fk) // KMX_DWORD CheckStatementOffsets(PFILE_KEYBOARD fk, PFILE_GROUP gp, PKMX_WCHAR context, PKMX_WCHAR output, PKMX_WCHAR key) -// KMX_BOOL CheckContextStatementPositions(PKMX_WCHAR context) +// void CheckContextStatementPositions(PKMX_WCHAR context) // KMX_DWORD CheckUseStatementsInOutput(PKMX_WCHAR output) // KMX_DWORD CheckVirtualKeysInOutput(PKMX_WCHAR output) // KMX_DWORD InjectContextToReadonlyOutput(PKMX_WCHAR pklOut) @@ -300,10 +276,10 @@ TEST_F(CompilerTest, ProcessKeyLineImpl_test) { // #11643: non-BMP characters do not makes sense for key codes u16cpy(str, u"+ 'A' > 'test'\n"); // baseline - EXPECT_EQ(CERR_None, ProcessKeyLineImpl(&fileKeyboard, str, TRUE, pklIn, pklKey, pklOut)); + EXPECT_EQ(STATUS_Success, ProcessKeyLineImpl(&fileKeyboard, str, TRUE, pklIn, pklKey, pklOut)); u16cpy(str, u"+ '\U00010000' > 'test'\n"); // surrogate pair - EXPECT_EQ(CERR_NonBMPCharactersNotSupportedInKeySection, ProcessKeyLineImpl(&fileKeyboard, str, TRUE, pklIn, pklKey, pklOut)); + EXPECT_EQ(KmnCompilerMessages::ERROR_NonBMPCharactersNotSupportedInKeySection, ProcessKeyLineImpl(&fileKeyboard, str, TRUE, pklIn, pklKey, pklOut)); delete[] pklIn; delete[] pklKey; @@ -672,22 +648,22 @@ TEST_F(CompilerTest, GetXStringImpl_test) { PKMX_WCHAR newp = nullptr; KMX_WCHAR token[128]; - // CERR_BufferOverflow, max=0 - EXPECT_EQ(CERR_BufferOverflow, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 0, 0, &newp, FALSE)); + // KmnCompilerMessages::FATAL_BufferOverflow, max=0 + EXPECT_EQ(KmnCompilerMessages::FATAL_BufferOverflow, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 0, 0, &newp, FALSE)); - // CERR_None, no token + // STATUS_Success, no token u16cpy(str, u""); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_NoTokensFound, empty + // KmnCompilerMessages::ERROR_NoTokensFound, empty u16cpy(str, u""); u16cpy(token, u"c"); - EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fileKeyboard, str, token, output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_NoTokensFound, GetXStringImpl(tstr, &fileKeyboard, str,token, output, 80, 0, &newp, FALSE)); - // CERR_NoTokensFound, whitespace + // KmnCompilerMessages::ERROR_NoTokensFound, whitespace u16cpy(str, u" "); u16cpy(token, u"c"); - EXPECT_EQ(CERR_NoTokensFound, GetXStringImpl(tstr, &fileKeyboard, str, token, output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_NoTokensFound, GetXStringImpl(tstr, &fileKeyboard, str, token, output, 80, 0, &newp, FALSE)); } // tests strings starting with 'x' or 'd' @@ -699,28 +675,28 @@ TEST_F(CompilerTest, GetXStringImpl_type_xd_test) { // hex 32-bit u16cpy(str, u"x10330"); // Gothic A - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_GothicA[] = { 0xD800, 0xDF30, 0 }; // see UTF32ToUTF16 EXPECT_EQ(0, u16cmp(tstr_GothicA, tstr)); // decimal 8-bit u16cpy(str, u"d18"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); // hex capital 8-bit u16cpy(str, u"X12"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"\u0012", tstr)); - // hex 32-bit, CERR_InvalidCharacter + // hex 32-bit, KmnCompilerMessages::ERROR_InvalidCharacter u16cpy(str, u"x110000"); - EXPECT_EQ(CERR_InvalidCharacter, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidCharacter, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // dk, valid u16cpy(str, u"dk(A)"); EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_dk_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; // setup deadkeys EXPECT_EQ(0, u16cmp(tstr_dk_valid, tstr)); fileKeyboard.cxDeadKeyArray = 0; @@ -728,22 +704,22 @@ TEST_F(CompilerTest, GetXStringImpl_type_xd_test) { // deadkey, valid u16cpy(str, u"deadkey(A)"); EXPECT_EQ(0, (int)fileKeyboard.cxDeadKeyArray); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_deadkey_valid[] = { UC_SENTINEL, CODE_DEADKEY, 1, 0 }; // setup deadkeys EXPECT_EQ(0, u16cmp(tstr_deadkey_valid, tstr)); fileKeyboard.cxDeadKeyArray = 0; - // dk, CERR_InvalidDeadkey, bad character + // dk, KmnCompilerMessages::ERROR_InvalidDeadkey, bad character u16cpy(str, u"dk(%)"); - EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // dk, CERR_InvalidDeadkey, no close delimiter => NULL + // dk, KmnCompilerMessages::ERROR_InvalidDeadkey, no close delimiter => NULL u16cpy(str, u"dk("); - EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // dk, CERR_InvalidDeadkey, empty delimiters => empty string + // dk, KmnCompilerMessages::ERROR_InvalidDeadkey, empty delimiters => empty string u16cpy(str, u"dk()"); - EXPECT_EQ(CERR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidDeadkey, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); } // tests strings starting with double quote @@ -755,18 +731,18 @@ TEST_F(CompilerTest, GetXStringImpl_type_double_quote_test) { // valid u16cpy(str, u"\"abc\""); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"abc", tstr)); - // CERR_UnterminatedString + // KmnCompilerMessages::ERROR_UnterminatedString u16cpy(str, u"\"abc"); - EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_ExtendedStringTooLong + // KmnCompilerMessages::ERROR_ExtendedStringTooLong u16cpy(str, u"\"abc\""); - EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error + EXPECT_EQ(KmnCompilerMessages::ERROR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - // CERR_StringInVirtualKeySection *** TODO *** + // KmnCompilerMessages::ERROR_StringInVirtualKeySection *** TODO *** } // tests strings starting with single quote @@ -778,18 +754,18 @@ TEST_F(CompilerTest, GetXStringImpl_type_single_quote_test) { // valid u16cpy(str, u"\'abc\'"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); EXPECT_EQ(0, u16cmp(u"abc", tstr)); - // CERR_UnterminatedString + // KmnCompilerMessages::ERROR_UnterminatedString u16cpy(str, u"\'abc"); - EXPECT_EQ(CERR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_UnterminatedString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_ExtendedStringTooLong + // KmnCompilerMessages::ERROR_ExtendedStringTooLong u16cpy(str, u"\'abc\'"); - EXPECT_EQ(CERR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error + EXPECT_EQ(KmnCompilerMessages::ERROR_ExtendedStringTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 2, 0, &newp, FALSE)); // max reduced to force error - // CERR_StringInVirtualKeySection *** TODO *** + // KmnCompilerMessages::ERROR_StringInVirtualKeySection *** TODO *** } // tests strings starting with 'a' @@ -805,59 +781,59 @@ TEST_F(CompilerTest, GetXStringImpl_type_a_test) { u16cpy(file_store[1].szName, u"b"); u16cpy(file_store[2].szName, u"c"); - // CERR_InvalidToken + // KmnCompilerMessages::ERROR_InvalidToken u16cpy(str, u"abc"); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_AnyInVirtualKeySection *** TODO *** + // KmnCompilerMessages::ERROR_AnyInVirtualKeySection *** TODO *** - // CERR_InvalidAny, no close delimiter => NULL + // KmnCompilerMessages::ERROR_InvalidAny, no close delimiter => NULL u16cpy(str, u"any("); - EXPECT_EQ(CERR_InvalidAny, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidAny, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_InvalidAny, empty delimiters => empty string + // KmnCompilerMessages::ERROR_InvalidAny, empty delimiters => empty string u16cpy(str, u"any()"); - EXPECT_EQ(CERR_InvalidAny, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidAny, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_InvalidAny, space in delimiters (see I11814, I11937, #11910, #11894, #11938) + // KmnCompilerMessages::ERROR_InvalidAny, space in delimiters (see I11814, I11937, #11910, #11894, #11938) u16cpy(str, u"any( )"); - EXPECT_EQ(CERR_InvalidAny, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidAny, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_StoreDoesNotExist + // KmnCompilerMessages::ERROR_StoreDoesNotExist u16cpy(str, u"any(d)"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_StoreDoesNotExist, space before store + // KmnCompilerMessages::ERROR_StoreDoesNotExist, space before store u16cpy(str, u"any( d)"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_StoreDoesNotExist, space after store + // KmnCompilerMessages::ERROR_StoreDoesNotExist, space after store u16cpy(str, u"any(d )"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // CERR_ZeroLengthString + // KmnCompilerMessages::ERROR_ZeroLengthString u16cpy(str, u"any(b)"); file_store[1].dpString = (PKMX_WCHAR)u""; - EXPECT_EQ(CERR_ZeroLengthString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_ZeroLengthString, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // valid u16cpy(str, u"any(b)"); file_store[1].dpString = (PKMX_WCHAR)u"abc"; // non-empty - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_any_valid[] = { UC_SENTINEL, CODE_ANY, 2, 0 }; EXPECT_EQ(0, u16cmp(tstr_any_valid, tstr)); // space before store, valid u16cpy(str, u"any( b)"); file_store[1].dpString = (PKMX_WCHAR)u"abc"; // non-empty - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_any_space_before_valid[] = { UC_SENTINEL, CODE_ANY, 2, 0 }; EXPECT_EQ(0, u16cmp(tstr_any_space_before_valid, tstr)); // space after store, valid (see I11937, #11938) u16cpy(str, u"any(b )"); file_store[1].dpString = (PKMX_WCHAR)u"abc"; // non-empty - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_any_space_after_valid[] = { UC_SENTINEL, CODE_ANY, 2, 0 }; EXPECT_EQ(0, u16cmp(tstr_any_space_after_valid, tstr)); } @@ -870,53 +846,53 @@ TEST_F(CompilerTest, GetXStringImpl_type_b_test) { KMX_WCHAR output[GLOBAL_BUFSIZE]; PKMX_WCHAR newp = nullptr; - // CERR_InvalidToken + // KmnCompilerMessages::ERROR_InvalidToken u16cpy(str, u"bcd"); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // beep, CERR_BeepInVirtualKeySection *** TODO *** + // beep, KmnCompilerMessages::ERROR_BeepInVirtualKeySection *** TODO *** // beep, valid u16cpy(str, u"beep"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_beep_valid[] = { UC_SENTINEL, CODE_BEEP, 0 }; EXPECT_EQ(0, u16cmp(tstr_beep_valid, tstr)); - // baselayout, CERR_90FeatureOnly_IfSystemStores + // baselayout, KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores fileKeyboard.version = VERSION_80; fileKeyboard.dwFlags = 0u; u16cpy(str, u"baselayout"); - EXPECT_EQ(CERR_90FeatureOnly_IfSystemStores, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); fileKeyboard.version = VERSION_90; - // baselayout, CERR_InvalidInVirtualKeySection *** TODO *** + // baselayout, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection *** TODO *** // baselayout, no close delimiter => NULL fileKeyboard.version = VERSION_90; u16cpy(str, u"baselayout("); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // baselayout, empty delimiters => empty string fileKeyboard.version = VERSION_90; u16cpy(str, u"baselayout()"); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // baselayout, space in delimiters (see I11814, I11937, #11910, #11894, #11938) fileKeyboard.version = VERSION_90; u16cpy(str, u"baselayout( )"); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // baselayout, CERR_InvalidToken from process_baselayout + // baselayout, KmnCompilerMessages::ERROR_InvalidToken from process_baselayout fileKeyboard.version = VERSION_90; u16cpy(str, u"baselayout(abc)"); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // baselayout, valid fileKeyboard.version = VERSION_90; fileKeyboard.cxStoreArray = 0; fileKeyboard.dpStoreArray = nullptr; u16cpy(str, u"baselayout(beep)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_baselayout_valid[] = { UC_SENTINEL, CODE_IFSYSTEMSTORE, TSS_BASELAYOUT+1, 2, 1, 0 }; EXPECT_EQ(0, u16cmp(tstr_baselayout_valid, tstr)); @@ -925,7 +901,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_b_test) { fileKeyboard.cxStoreArray = 0; fileKeyboard.dpStoreArray = nullptr; u16cpy(str, u"baselayout( beep)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_baselayout_space_before_valid[] = { UC_SENTINEL, CODE_IFSYSTEMSTORE, TSS_BASELAYOUT+1, 2, 1, 0 }; EXPECT_EQ(0, u16cmp(tstr_baselayout_space_before_valid, tstr)); @@ -934,7 +910,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_b_test) { fileKeyboard.cxStoreArray = 0; fileKeyboard.dpStoreArray = nullptr; u16cpy(str, u"baselayout(beep )"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_baselayout_space_after_valid[] = { UC_SENTINEL, CODE_IFSYSTEMSTORE, TSS_BASELAYOUT+1, 2, 1, 0 }; EXPECT_EQ(0, u16cmp(tstr_baselayout_space_after_valid, tstr)); } @@ -953,56 +929,56 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { u16cpy(option[1].szName, u"b"); u16cpy(option[2].szName, u"c"); - // CERR_InvalidToken + // KmnCompilerMessages::ERROR_InvalidToken u16cpy(str, u"ijk"); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // if, CERR_80FeatureOnly + // if, KmnCompilerMessages::ERROR_80FeatureOnly fileKeyboard.version = VERSION_70; fileKeyboard.dwFlags = 0u; u16cpy(str, u"if"); - EXPECT_EQ(CERR_80FeatureOnly, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_80FeatureOnly, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); fileKeyboard.version = VERSION_80; - // if, CERR_InvalidInVirtualKeySection *** TODO *** + // if, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection *** TODO *** // if, no close delimiter => NULL fileKeyboard.version = VERSION_80; u16cpy(str, u"if("); - EXPECT_EQ(CERR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // if, empty delimiters => empty string fileKeyboard.version = VERSION_80; fileKeyboard.dwFlags = 0u; u16cpy(str, u"if()"); - EXPECT_EQ(CERR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // if, space in delimiters (see I11814, I11937, #11910, #11894, #11938) fileKeyboard.version = VERSION_80; fileKeyboard.dwFlags = 0u; u16cpy(str, u"if( )"); - EXPECT_EQ(CERR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // if, invalid fileKeyboard.version = VERSION_80; u16cpy(str, u"if(abc)"); - EXPECT_EQ(CERR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIf, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // if, CERR_90FeatureOnly_IfSystemStores + // if, KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores fileKeyboard.version = VERSION_80; u16cpy(str, u"if(&BITMAP=)"); - EXPECT_EQ(CERR_90FeatureOnly_IfSystemStores, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_90FeatureOnly_IfSystemStores, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // if, CERR_IfSystemStore_NotFound + // if, KmnCompilerMessages::ERROR_IfSystemStore_NotFound fileKeyboard.version = VERSION_90; u16cpy(str, u"if(&abc=)"); - EXPECT_EQ(CERR_IfSystemStore_NotFound, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_IfSystemStore_NotFound, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // if, system store, equal, valid fileKeyboard.version = VERSION_90; fileKeyboard.cxStoreArray = 3u; u16cpy(str, u"if(&BITMAP=beep)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_if_equal_system_store_valid[] = { UC_SENTINEL, CODE_IFSYSTEMSTORE, 2, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_if_equal_system_store_valid, tstr)); @@ -1010,14 +986,14 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.version = VERSION_90; fileKeyboard.cxStoreArray = 3u; u16cpy(str, u"if(&BITMAP!=beep)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_if_not_equal_system_store_valid[] = { UC_SENTINEL, CODE_IFSYSTEMSTORE, 2, 1, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_if_not_equal_system_store_valid, tstr)); - // if, option, CERR_StoreDoesNotExist + // if, option, KmnCompilerMessages::ERROR_StoreDoesNotExist fileKeyboard.version = VERSION_80; u16cpy(str, u"if(d=beep)"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // if, option, equal, valid fileKeyboard.version = VERSION_80; @@ -1025,7 +1001,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.dpStoreArray = option; option[1].fIsOption = TRUE; u16cpy(str, u"if(b=beep)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_if_option_valid[] = { UC_SENTINEL, CODE_IFOPT, 2, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_if_option_valid, tstr)); @@ -1035,7 +1011,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.dpStoreArray = option; option[1].fIsOption = TRUE; u16cpy(str, u"if(b =beep)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_if_option_space_before_assign_valid[] = { UC_SENTINEL, CODE_IFOPT, 2, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_if_option_space_before_assign_valid, tstr)); @@ -1045,7 +1021,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.dpStoreArray = option; option[1].fIsOption = TRUE; u16cpy(str, u"if(b= beep)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_if_option_space_before_rhs_valid[] = { UC_SENTINEL, CODE_IFOPT, 2, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_if_option_space_before_rhs_valid, tstr)); @@ -1055,7 +1031,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.dpStoreArray = option; option[1].fIsOption = TRUE; u16cpy(str, u"if(b=beep )"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_if_option_space_after_rhs_valid[] = { UC_SENTINEL, CODE_IFOPT, 2, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_if_option_space_after_rhs_valid, tstr)); @@ -1068,53 +1044,53 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { u16cpy(file_store[1].szName, u"b"); u16cpy(file_store[2].szName, u"c"); - // index, CERR_InvalidInVirtualKeySection *** TODO *** + // index, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection *** TODO *** // index, no close delimiter => NULL u16cpy(str, u"index("); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, empty delimiters => empty string u16cpy(str, u"index()"); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, space in delimiters (see I11814, I11937, #11910, #11894, #11938) u16cpy(str, u"index( )"); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, no comma or space u16cpy(str, u"index(b)"); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, no comma, space before store u16cpy(str, u"index( b)"); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, no comma, space after store u16cpy(str, u"index(b )"); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // index, CERR_StoreDoesNotExist + // index, KmnCompilerMessages::ERROR_StoreDoesNotExist u16cpy(str, u"index(d,4)"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, comma, offset=0 fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index(b,0)"); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, comma, negative offset fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index(b,-1)"); - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // index, comma, valid fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index(b,4)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_index_comma_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_index_comma_valid, tstr)); @@ -1122,7 +1098,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index( b,4)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_index_initial_space_and_comma_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_index_initial_space_and_comma_valid, tstr)); @@ -1130,7 +1106,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index(b, 4)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_index_comma_and_space_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_index_comma_and_space_valid, tstr)); @@ -1138,7 +1114,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { u16cpy(str, u"index(b 4)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_index_space_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; EXPECT_EQ(0, u16cmp(tstr_index_space_valid, tstr)); @@ -1146,33 +1122,33 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { u16cpy(str, u"index(b,42)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_index_two_digit_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 42, 0 }; EXPECT_EQ(0, u16cmp(tstr_index_two_digit_valid, tstr)); - // index, comma, non-digit parameter, CERR_InvalidIndex + // index, comma, non-digit parameter, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b,g)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // index, comma, no parameter, CERR_InvalidIndex + // index, comma, no parameter, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b,)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // index, space and comma, no parameter, CERR_InvalidIndex + // index, space and comma, no parameter, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b ,)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // index, comma, no parameter but space, CERR_InvalidIndex + // index, comma, no parameter but space, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b, )"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; - EXPECT_EQ(CERR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); } // tests strings starting with 'o' @@ -1190,61 +1166,61 @@ TEST_F(CompilerTest, GetXStringImpl_type_o_test) { u16cpy(file_store[1].szName, u"b"); u16cpy(file_store[2].szName, u"c"); - // CERR_InvalidToken + // KmnCompilerMessages::ERROR_InvalidToken u16cpy(str, u"opq"); - EXPECT_EQ(CERR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // outs, CERR_OutsInVirtualKeySection *** TODO *** + // outs, KmnCompilerMessages::ERROR_OutsInVirtualKeySection *** TODO *** // outs, no close delimiter => NULL u16cpy(str, u"outs("); - EXPECT_EQ(CERR_InvalidOuts, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidOuts, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // outs, empty delimiters => empty string u16cpy(str, u"outs()"); - EXPECT_EQ(CERR_InvalidOuts, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidOuts, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); // outs, space in delimiters (see I11814, I11937, #11910, #11894, #11938) u16cpy(str, u"outs( )"); - EXPECT_EQ(CERR_InvalidOuts, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidOuts, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // outs, CERR_StoreDoesNotExist + // outs, KmnCompilerMessages::ERROR_StoreDoesNotExist u16cpy(str, u"outs(d)"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // outs, CERR_StoreDoesNotExist, space before store + // outs, KmnCompilerMessages::ERROR_StoreDoesNotExist, space before store u16cpy(str, u"outs( d)"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // outs, CERR_StoreDoesNotExist, space after store + // outs, KmnCompilerMessages::ERROR_StoreDoesNotExist, space after store u16cpy(str, u"outs(d )"); - EXPECT_EQ(CERR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // outs, CERR_OutsTooLong + // outs, KmnCompilerMessages::ERROR_OutsTooLong PKMX_WCHAR dpString = (PKMX_WCHAR)u"abc"; - file_store[1].dpString = dpString; // length 4 => max should be > 4, otherwise a CERR_OutsTooLong is emitted + file_store[1].dpString = dpString; // length 4 => max should be > 4, otherwise a ERROR_OutsTooLong is emitted int max = u16len(dpString) + 1; // 4, including terminating '\0' u16cpy(str, u"outs(b)"); - EXPECT_EQ(CERR_OutsTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, max, 0, &newp, FALSE)); // max reduced to force error + EXPECT_EQ(KmnCompilerMessages::ERROR_OutsTooLong, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, max, 0, &newp, FALSE)); // max reduced to force error // outs, valid file_store[1].dpString = (PKMX_WCHAR)u"abc"; u16cpy(str, u"outs(b)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_outs_valid[] = { 'a', 'b', 'c', 0 }; EXPECT_EQ(0, u16cmp(tstr_outs_valid, tstr)); // outs, space before store, valid file_store[1].dpString = (PKMX_WCHAR)u"abc"; u16cpy(str, u"outs( b)"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_outs_space_before_valid[] = { 'a', 'b', 'c', 0 }; EXPECT_EQ(0, u16cmp(tstr_outs_space_before_valid, tstr)); // outs, space after store, valid (see I11937, #11938) file_store[1].dpString = (PKMX_WCHAR)u"abc"; u16cpy(str, u"outs(b )"); - EXPECT_EQ(CERR_None, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); const KMX_WCHAR tstr_outs_space_after_valid[] = { 'a', 'b', 'c', 0 }; EXPECT_EQ(0, u16cmp(tstr_outs_space_after_valid, tstr)); } @@ -1262,25 +1238,25 @@ TEST_F(CompilerTest, GetXStringImpl_type_o_test) { // int GetGroupNum(PFILE_KEYBOARD fk, PKMX_WCHAR p) TEST_F(CompilerTest, ProcessEthnologueStore_test) { - EXPECT_EQ(CERR_None, ProcessEthnologueStore((PKMX_WCHAR)u"abc")); - EXPECT_EQ(CWARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u";abc")); - EXPECT_EQ(CWARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u",abc")); - EXPECT_EQ(CERR_None, ProcessEthnologueStore((PKMX_WCHAR)u" abc")); - EXPECT_EQ(CERR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abc ")); - EXPECT_EQ(CERR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abcd")); - EXPECT_EQ(CERR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"ab")); - EXPECT_EQ(CERR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"a")); - EXPECT_EQ(CERR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"a2b")); - EXPECT_EQ(CERR_None, ProcessEthnologueStore((PKMX_WCHAR)u"")); // needs correcting ... see #11955 - EXPECT_EQ(CERR_None, ProcessEthnologueStore((PKMX_WCHAR)u"abc def")); - EXPECT_EQ(CERR_None, ProcessEthnologueStore((PKMX_WCHAR)u"abc def")); - EXPECT_EQ(CWARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abc,def")); - EXPECT_EQ(CWARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abc;def")); + EXPECT_EQ(STATUS_Success, ProcessEthnologueStore((PKMX_WCHAR)u"abc")); + EXPECT_EQ(KmnCompilerMessages::WARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u";abc")); + EXPECT_EQ(KmnCompilerMessages::WARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u",abc")); + EXPECT_EQ(STATUS_Success, ProcessEthnologueStore((PKMX_WCHAR)u" abc")); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abc ")); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abcd")); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"ab")); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"a")); + EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"a2b")); + EXPECT_EQ(STATUS_Success, ProcessEthnologueStore((PKMX_WCHAR)u"")); // needs correcting ... see #11955 + EXPECT_EQ(STATUS_Success, ProcessEthnologueStore((PKMX_WCHAR)u"abc def")); + EXPECT_EQ(STATUS_Success, ProcessEthnologueStore((PKMX_WCHAR)u"abc def")); + EXPECT_EQ(KmnCompilerMessages::WARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abc,def")); + EXPECT_EQ(KmnCompilerMessages::WARN_PunctuationInEthnologueCode, ProcessEthnologueStore((PKMX_WCHAR)u"abc;def")); } // KMX_DWORD ProcessHotKey(PKMX_WCHAR p, KMX_DWORD *hk) // void SetChecksum(PKMX_BYTE buf, PKMX_DWORD CheckSum, KMX_DWORD sz) -// KMX_BOOL kmcmp::CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall) +// void kmcmp::CheckStoreUsage(PFILE_KEYBOARD fk, int storeIndex, KMX_BOOL fIsStore, KMX_BOOL fIsOption, KMX_BOOL fIsCall) // KMX_DWORD WriteCompiledKeyboard(PFILE_KEYBOARD fk, KMX_BYTE**data, size_t& dataSize) // KMX_DWORD ReadLine(KMX_BYTE* infile, int sz, int& offset, PKMX_WCHAR wstr, KMX_BOOL PreProcess) @@ -1288,17 +1264,17 @@ TEST_F(CompilerTest, GetRHS_test) { KMX_WCHAR str[LINESIZE]; KMX_WCHAR tstr[128]; - // CERR_NoTokensFound, empty string + // KmnCompilerMessages::ERROR_NoTokensFound, empty string u16cpy(str, u""); - EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_NoTokensFound, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); - // CERR_NoTokensFound, no '>' + // KmnCompilerMessages::ERROR_NoTokensFound, no '>' u16cpy(str, u"abc"); - EXPECT_EQ(CERR_NoTokensFound, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); + EXPECT_EQ(KmnCompilerMessages::ERROR_NoTokensFound, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); - // CERR_None + // STATUS_Success u16cpy(str, u"> nul c\n"); - EXPECT_EQ(CERR_None, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); + EXPECT_EQ(STATUS_Success, GetRHS(&fileKeyboard, str, tstr, 80, 0, FALSE)); } // void safe_wcsncpy(PKMX_WCHAR out, PKMX_WCHAR in, int cbMax) @@ -1326,7 +1302,7 @@ TEST_F(CompilerTest, isIntegerWstring_test) { } // KMX_DWORD kmcmp::UTF32ToUTF16(int n, int *n1, int *n2) -// KMX_DWORD BuildVKDictionary(PFILE_KEYBOARD fk) +// KMX_BOOL BuildVKDictionary(PFILE_KEYBOARD fk) // int GetVKCode(PFILE_KEYBOARD fk, PKMX_WCHAR p) // int GetDeadKey(PFILE_KEYBOARD fk, PKMX_WCHAR p) // void kmcmp::RecordDeadkeyNames(PFILE_KEYBOARD fk) diff --git a/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp b/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp deleted file mode 100644 index 9fea4670c3..0000000000 --- a/developer/src/kmcmplib/tests/gtest-compmsg-test.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "../../common/include/kmn_compiler_errors.h" -#include "../../../../common/include/km_types.h" - -const KMX_CHAR *GetCompilerErrorString(KMX_DWORD code); - -class CompMsgTest : public testing::Test { - protected: - CompMsgTest() {} - ~CompMsgTest() override {} - void SetUp() override {} - void TearDown() override {} -}; - -TEST_F(CompMsgTest, GetCompilerErrorString) { - EXPECT_EQ(nullptr, GetCompilerErrorString(CERR_None)); - EXPECT_EQ(nullptr, GetCompilerErrorString(0x00004FFF)); // top of range ERROR - EXPECT_EQ("Invalid 'layout' command", GetCompilerErrorString(CERR_InvalidLayoutLine)); -}; \ No newline at end of file diff --git a/developer/src/kmcmplib/tests/kmcompxtest.cpp b/developer/src/kmcmplib/tests/kmcompxtest.cpp index 4e4b91e830..827199967e 100644 --- a/developer/src/kmcmplib/tests/kmcompxtest.cpp +++ b/developer/src/kmcmplib/tests/kmcompxtest.cpp @@ -24,11 +24,6 @@ using namespace std; -#define CERR_FATAL 0x00008000 -#define CERR_ERROR 0x00004000 -#define CERR_WARNING 0x00002000 -#define CERR_HINT 0x00001000 - int main(int argc, char *argv[]) { if(argc < 4) { @@ -53,8 +48,7 @@ int main(int argc, char *argv[]) if(*p == '\\') *p = '/'; } - char first5[6] = "CERR_"; - char* pfirst5 = first5; + const char* first5 = "CERR_"; KMCMP_COMPILER_RESULT result; KMCMP_COMPILER_OPTIONS options; @@ -66,7 +60,7 @@ int main(int argc, char *argv[]) if(kmcmp_CompileKeyboard(kmn_file, options, msgproc, loadfileProc, nullptr, result)) { char* testname = strrchr( (char*) kmn_file, '/') + 1; - if(strncmp(testname, pfirst5, 5) == 0){ + if(strncmp(testname, first5, strlen(first5)) == 0){ return __LINE__; // exit code: CERR_ in Name + no Error found } @@ -99,7 +93,7 @@ int main(int argc, char *argv[]) char* testname = strrchr( (char*) kmn_file, '/') + 1; // Does testname contain CERR_ && contains '_' on pos 9 ? -> Get ErrorValue - if ((strncmp(testname, pfirst5, 5) == 0) && (testname[9] == '_')) { + if ((strncmp(testname, first5, strlen(first5)) == 0) && (testname[9] == '_')) { char* ErrNr = strchr(testname, '_') +1 ; std::istringstream(ErrNr) >> std::hex >> error_val; diff --git a/developer/src/kmcmplib/tests/meson.build b/developer/src/kmcmplib/tests/meson.build index a2827ef47d..a5b6476c88 100644 --- a/developer/src/kmcmplib/tests/meson.build +++ b/developer/src/kmcmplib/tests/meson.build @@ -168,17 +168,6 @@ gtestcompilertest = executable('gtest-compiler-test', 'gtest-compiler-test.cpp', test('gtest-compiler-test', gtestcompilertest) -gtestcompmsgtest = executable('gtest-compmsg-test', 'gtest-compmsg-test.cpp', - cpp_args: defns + flags, - include_directories: inc, - name_suffix: name_suffix, - link_args: links + tests_links, - objects: lib.extract_all_objects(), - dependencies: [ icuuc_dep, gtest_dep, gmock_dep ], - ) - -test('gtest-compmsg-test', gtestcompmsgtest) - gtestkmx_u16test = executable('gtest-kmx_u16-test', 'gtest-kmx_u16-test.cpp', cpp_args: defns + flags, include_directories: inc, diff --git a/developer/src/kmcmplib/tests/util_callbacks.cpp b/developer/src/kmcmplib/tests/util_callbacks.cpp index fdfd28b375..d512463a0b 100644 --- a/developer/src/kmcmplib/tests/util_callbacks.cpp +++ b/developer/src/kmcmplib/tests/util_callbacks.cpp @@ -7,53 +7,57 @@ std::vector error_vec; -int msgproc(int line, uint32_t dwMsgCode, const char* szText, void* context) { - error_vec.push_back(dwMsgCode); +void msgproc(const KMCMP_COMPILER_RESULT_MESSAGE &message, void* context) { + error_vec.push_back(message.errorCode); const char*t = "unknown"; - switch(dwMsgCode & 0xF000) { - case CERR_HINT: t=" hint"; break; - case CERR_WARNING: t="warning"; break; - case CERR_ERROR: t=" error"; break; - case CERR_FATAL: t=" fatal"; break; + switch(message.errorCode & MESSAGE_SEVERITY_MASK) { + case CompilerErrorSeverity::Hint: t=" SevHint"; break; + case CompilerErrorSeverity::Warn: t=" SevWarn"; break; + case CompilerErrorSeverity::Error: t="SevError"; break; + case CompilerErrorSeverity::Fatal: t="SevFatal"; break; + case CompilerErrorSeverity::Info: t=" SevInfo"; break; } - printf("line %d %s %4.4x: %s\n", line, t, (unsigned int)dwMsgCode, szText); - return 1; + printf("[CompilerMessage] %s(%d): %s | 0x%3.3x (", + message.filename.c_str(), + message.lineNumber, + t, + (unsigned int)message.errorCode & MESSAGE_BASEERROR_MASK + ); + for(auto it = message.parameters.begin(); it != message.parameters.end(); it++) { + printf("%s'%s'", it == message.parameters.begin() ? "" : ", ", it->c_str()); + } + printf(")\n"); } -bool loadfileProc(const char* filename, const char* baseFilename, void* data, int* size, void* context) { +const std::vector loadfileProc(const std::string& filename, const std::string& baseFilename) { std::string resolvedFilename = filename; - if(baseFilename && *baseFilename && IsRelativePath(filename)) { + if(baseFilename.length() && IsRelativePath(filename.c_str())) { char* p; - if ((p = strrchr_slash((char*)baseFilename)) != nullptr) { - std::string basePath = std::string(baseFilename, (int)(p - baseFilename + 1)); - resolvedFilename = basePath; + const char *base = baseFilename.c_str(); + if ((p = strrchr_slash((char*)base)) != nullptr) { + resolvedFilename = std::string(baseFilename, 0, (int)(p - base + 1)); resolvedFilename.append(filename); } } + std::vector buf; + FILE* fp = Open_File(resolvedFilename.c_str(), "rb"); if(!fp) { - return false; + return buf; } - if(!data) { - // return size - if(fseek(fp, 0, SEEK_END) != 0) { - fclose(fp); - return false; - } - *size = ftell(fp); - if(*size == -1L) { - fclose(fp); - return false; - } - } else { - // return data - if(fread(data, 1, *size, fp) != (size_t)(*size)) { - fclose(fp); - return false; - } + if(fseek(fp, 0, SEEK_END) != 0) { + fclose(fp); + return buf; + } + size_t size = ftell(fp); + + buf.resize(size); + fseek(fp, 0, SEEK_SET); + if(fread(buf.data(), 1, size, fp) != size) { + buf.resize(0); } fclose(fp); - return true; + return buf; } diff --git a/developer/src/kmcmplib/tests/util_callbacks.h b/developer/src/kmcmplib/tests/util_callbacks.h index 345de64b9f..6c208b9d4d 100644 --- a/developer/src/kmcmplib/tests/util_callbacks.h +++ b/developer/src/kmcmplib/tests/util_callbacks.h @@ -2,7 +2,7 @@ #include -int msgproc(int line, uint32_t dwMsgCode, const char* szText, void* context); -bool loadfileProc(const char* filename, const char* baseFilename, void* data, int* size, void* context); +void msgproc(const KMCMP_COMPILER_RESULT_MESSAGE &message, void* context); +const std::vector loadfileProc(const std::string& filename, const std::string& baseFilename); extern std::vector error_vec; \ No newline at end of file diff --git a/developer/src/server/tsconfig.json b/developer/src/server/tsconfig.json index 4781eb53e4..c17961206f 100644 --- a/developer/src/server/tsconfig.json +++ b/developer/src/server/tsconfig.json @@ -22,4 +22,8 @@ "include": [ "src/**/*.ts" ], + "references": [ + { "path": "../../../common/web/keyman-version" }, + { "path": "../common/web/utils" }, + ] } diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index 00aaeef0b3..0107491dda 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -53,9 +53,13 @@ sudo mk-build-deps --install linux/debian/control #### Node.js -Node.js v18 is required for Core builds, Web builds, and Developer command line tool builds and usage. +Node.js is required for Core builds, Web builds, and Developer command line tool builds and usage. -Follow the instructions on the [NodeSource Distributions](https://github.com/nodesource/distributions#table-of-contents) page. +Our recommended way to install node.js is with +[nvm](https://github.com/nvm-sh/nvm). This makes it easy to switch between +versions of node.js. + +See [node.md](node.md) for more information. #### Emscripten diff --git a/docs/build/macos.md b/docs/build/macos.md index 26ece4a6d6..81b1bcd0e7 100644 --- a/docs/build/macos.md +++ b/docs/build/macos.md @@ -77,10 +77,24 @@ PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH" ## KeymanWeb Dependencies -* node.js 22+, emscripten 3.1.46 or later +* node.js, emscripten 3.1.46 or later + +### node.js + +Our recommended way to install node.js is with +[nvm](https://github.com/nvm-sh/nvm). This makes it easy to switch between +versions of node.js. + +Alternatively, you can install node.js with `brew`. + +See [node.md](node.md) for more information. + +### emscripten + +To install emscripten: ```shell -brew install node emscripten +brew install emscripten ``` Note: if you install emscripten with brew on macOS, only emscripten binaries are diff --git a/docs/build/node.md b/docs/build/node.md new file mode 100644 index 0000000000..da0a96e1fd --- /dev/null +++ b/docs/build/node.md @@ -0,0 +1,71 @@ +# Node use in the Keyman project + +For a given release cycle, we select and pin to a specific version of node.js, +and try to use that throughout. The version in use can be found in +`package.json/engines.node`. + +If we encounter a blocking issue, we will upgrade to a known-good release, but +this is exceptional. + +Generally, as a developer, if you use the same major version as is found in +package.json, you probably won't have significant issues. However, if you are +switching between stable branches and alpha branches, you may find the required +node version changes. + +## Automatic node version selection + +The Keyman build system can be configured to manage the node.js version for you. +This does have several caveats, so it is not enabled by default. + +When this is enabled, the build system will download the required node version +and make it available on the PATH, and it will also stop the build if the node +version mismatches. This happens in `build.sh configure` steps for any +Typescript/Javascript project. + +To enable automatic node version selection, add the variable `KEYMAN_USE_NVM=1` +to your environment. + +### Caveats + +nvm (for macOS/Linux) and nvm-windows use somewhat different paradigms, so the +caveats vary per platform. + +### Caveats on macOS/Linux + +On macOS/Linux, nvm is provided as a shell function that modifies the current +environment PATH to make a specific node version available -- and so this does +not affect unrelated processes. + +1. You must use [nvm](https://github.com/nvm-sh/nvm) (macOS/Linux) to install + and manage Node versions. +2. The Keyman build environment will create a symlink at `~/.keyman/node` + pointing to the version of node selected by nvm. +3. You should add `$HOME/.keyman/node` to the front of your `PATH` variable, + e.g. in `~/.bash_profile`. This means that the node version _will_ be set for + the entire system, unlike with standard nvm usage. This allows build scripts + to run without calling `nvm` for each invocation. + +### Caveats on Windows + +On Windows, nvm-windows creates a symlink to the current node version, and +this symlink is what is on the system PATH, so it affects all processes on the +system. + +1. You must use [nvm-windows](https://github.com/coreybutler/nvm-windows) to + install and manage Node versions. +2. By default on Windows, creating symlinks requires elevation. While + nvm-windows does this for you, it can be irritating to have a build script + pause for elevation. In Local Group Policy Editor, `Computer Configuration`, + `Windows Settings`, `Security Settings`, `Local Policies`, + `User Rights Assignment`, you can add your username to the + `Create symbolic links` policy (and reboot), to avoid elevation. + +## Build Agents + +The Keyman build agents use nvm as described above, including the caveats. + +## Implementation + +See `_select_node_version_with_nvm()` in +`/resources/build/shellHelperFunctions.sh`, and +`/resources/build/_builder_nvm.sh`. \ No newline at end of file diff --git a/docs/build/windows.md b/docs/build/windows.md index 99f1b44e28..dcb55ce4a4 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -206,7 +206,15 @@ installed emsdk (most likely %LocalAppData%\emsdk\upstream\emscripten) **Environment variables**: * `EMSCRIPTEN_BASE`: `\upstream\emscripten` -After installing emscripten, you'll need to install node.js and openjdk: +After installing emscripten, you'll need to install node.js and openjdk. + +#### node.js + +Our recommended way to install node.js is to use +[nvm-windows](https://github.com/coreybutler/nvm-windows). This makes it +easy to switch between versions of node.js. + +Alternatively, use Powershell + Chocolatey to install node.js: ```ps1 # Elevated PowerShell @@ -214,9 +222,23 @@ After installing emscripten, you'll need to install node.js and openjdk: # for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) $ProgressPreference = 'SilentlyContinue' choco install nodejs +``` + +See [node.md](node.md) for more information. + +#### openjdk + +Use Powershell + Chocolatey to install OpenJDK: + +```ps1 +# Elevated PowerShell + +# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) +$ProgressPreference = 'SilentlyContinue' choco install openjdk ``` + ### Windows Platform Dependencies **Projects**: diff --git a/docs/minimum-versions.md b/docs/minimum-versions.md index adb4edc687..ec6a1c1626 100644 --- a/docs/minimum-versions.md +++ b/docs/minimum-versions.md @@ -60,7 +60,7 @@ https://help.keyman.com/developer/engine/android/latest-version/ | KEYMAN_MIN_VERSION_CPP | 17 | | KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.44 | | KEYMAN_MIN_VERSION_MESON | 1.0.0 | -| KEYMAN_MIN_VERSION_NODE_MAJOR | 18 | +| KEYMAN_MIN_VERSION_NODE_MAJOR | 20 | | KEYMAN_MIN_VERSION_NPM | 10.5.1 | | KEYMAN_MIN_VERSION_VISUAL_STUDIO | 2019 | | KEYMAN_VERSION_JAVA | 11 | diff --git a/package-lock.json b/package-lock.json index 9f71278589..2f2ca04142 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,7 +66,7 @@ "typescript": "^5.4.5" }, "engines": { - "node": "^18.x" + "node": "20.16.0" } }, "common/models/templates": { diff --git a/package.json b/package.json index 02ff65534a..638f2b2fad 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,6 @@ "@keymanapp/ldml-keyboard-constants": "file:core/include/ldml" }, "engines": { - "node": "^18.x" + "node": "20.16.0" } } diff --git a/resources/build/_builder_nvm.sh b/resources/build/_builder_nvm.sh new file mode 100755 index 0000000000..cccbb6b055 --- /dev/null +++ b/resources/build/_builder_nvm.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# See also /docs/build/node.md + +set -e +set -u + +if [[ $# -lt 1 ]]; then + echo "This script is called by shellHelperFunctions.sh, _select_node_version_with_nvm()" + echo "during build.sh configure steps. It is not intended to be called directly, as it" + echo "is a wrapper for nvm." + exit 99 +fi + +REQUIRED_NODE_VERSION="$1" + +if [[ -z "${NVM_DIR+x}" ]]; then + export NVM_DIR="$HOME/.nvm" +fi + +# +# nvm on macos and linux is a shell function. `source`ing it into our scripts is +# fragile because it uses some of the same variable names that we do. We have +# marked our most precious variables as `readonly`, which breaks nvm re-use of +# them also! Safest way to work around this is to load nvm in a child process +# and run it there. Downside is then of course we don't get the `PATH` changes +# that nvm does for us, so we have to do it ourselves back in the caller, +# `_select_node_version_with_nvm()`. +# +# Note: the readonly attribute for variables is not inherited by child +# processes. +# +# See also https://github.com/nvm-sh/nvm/issues/3257 (among others) +# + +type -t nvm >/dev/null || { + source "$NVM_DIR/nvm.sh" + type -t nvm >/dev/null || { + echo "Failed to find nvm" + exit 1 + } +} + +nvm install "$REQUIRED_NODE_VERSION" +nvm use "$REQUIRED_NODE_VERSION" + +# Beware the hardcoded path below -- it should already be in the system PATH + +mkdir -p "$HOME/.keyman" +rm -f "$HOME/.keyman/node" +ln -s "$NVM_BIN" "$HOME/.keyman/node" diff --git a/resources/build/jq.inc.sh b/resources/build/jq.inc.sh index cf68aaf4b2..d1d7c32c23 100644 --- a/resources/build/jq.inc.sh +++ b/resources/build/jq.inc.sh @@ -6,27 +6,29 @@ # Linux/macOS: jq # -## START STANDARD BUILD SCRIPT INCLUDE -# adjust relative paths as necessary -JQ_THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" -# . "${THIS_SCRIPT%/*}/build-utils.sh" -## END STANDARD BUILD SCRIPT INCLUDE +if [[ -z "${JQ+x}" ]]; then + ## START STANDARD BUILD SCRIPT INCLUDE + # adjust relative paths as necessary + JQ_THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" + # . "${THIS_SCRIPT%/*}/build-utils.sh" + ## END STANDARD BUILD SCRIPT INCLUDE -case "${OSTYPE}" in - "cygwin") - JQ=$(dirname "$JQ_THIS_SCRIPT")/jq-win64.exe - ;; - "msys") - JQ=$(dirname "$JQ_THIS_SCRIPT")/jq-win64.exe - ;; - *) - JQ=jq - ;; -esac + case "${OSTYPE}" in + "cygwin") + JQ=$(dirname "$JQ_THIS_SCRIPT")/jq-win64.exe + ;; + "msys") + JQ=$(dirname "$JQ_THIS_SCRIPT")/jq-win64.exe + ;; + *) + JQ=jq + ;; + esac -readonly JQ + readonly JQ -# JQ with inplace file replacement -function jqi() { - cat <<< "$($JQ -c "$1" < "$2")" > "$2" -} + # JQ with inplace file replacement + function jqi() { + cat <<< "$($JQ -c "$1" < "$2")" > "$2" + } +fi \ No newline at end of file diff --git a/resources/build/minimum-versions.inc.sh b/resources/build/minimum-versions.inc.sh index 17757d5584..ff49c867f1 100644 --- a/resources/build/minimum-versions.inc.sh +++ b/resources/build/minimum-versions.inc.sh @@ -13,7 +13,7 @@ KEYMAN_MIN_TARGET_VERSION_UBUNTU=20.04 # Ubuntu 20.04 Focal KEYMAN_MIN_TARGET_VERSION_CHROME=95.0 # Final version that runs on Android 5.0 # Dependency versions -KEYMAN_MIN_VERSION_NODE_MAJOR=18 +KEYMAN_MIN_VERSION_NODE_MAJOR=20 # node version source of truth is /package.json:/engines/node KEYMAN_MIN_VERSION_NPM=10.5.1 # 10.5.0 has bug, discussed in #10350 KEYMAN_MIN_VERSION_EMSCRIPTEN=3.1.44 # Warning: 3.1.45 is bad (#9529); newer versions work KEYMAN_MAX_VERSION_EMSCRIPTEN=3.1.58 # See #9529 diff --git a/resources/shellHelperFunctions.sh b/resources/shellHelperFunctions.sh index e93b2ed50c..7ded208d44 100755 --- a/resources/shellHelperFunctions.sh +++ b/resources/shellHelperFunctions.sh @@ -1,5 +1,16 @@ #!/usr/bin/env bash +# We only import JQ if not already defined; jq is used by +# _select_node_version_with_nvm() + +if [[ -z "${JQ+x}" ]]; then + if [[ "$BUILDER_OS" == win ]]; then + . "$KEYMAN_ROOT/resources/build/jq.inc.sh" + else + JQ=jq + fi +fi + # Allows for a quick macOS check for those scripts requiring a macOS environment. verify_on_mac() { if [[ "${OSTYPE}" != "darwin"* ]]; then @@ -243,6 +254,13 @@ verify_npm_setup() { fi builder_set_module_has_been_built /external/npm-ci + # If we are on CI environment, automatically select a node version with nvm + # Also, a developer can set KEYMAN_USE_NVM variable to get this behaviour + # automatically too (see /docs/build/node.md) + if [[ "$VERSION_ENVIRONMENT" != local || ! -z "${KEYMAN_USE_NVM+x}" ]]; then + _select_node_version_with_nvm + fi + # Check if Node.JS/npm is installed. type npm >/dev/null ||\ builder_die "Build environment setup error detected! Please ensure Node.js is installed!" @@ -252,4 +270,29 @@ verify_npm_setup() { try_multiple_times npm ci popd > /dev/null -} \ No newline at end of file +} + +# Use nvm to select a node version according to package.json +# see /docs/build/node.md +_select_node_version_with_nvm() { + local REQUIRED_NODE_VERSION="$("$JQ" -r '.engines.node' "$KEYMAN_ROOT/package.json")" + + if [[ $BUILDER_OS != win ]]; then + # launch nvm in a sub process, see _builder_nvm.sh for details + "$KEYMAN_ROOT/resources/build/_builder_nvm.sh" "$REQUIRED_NODE_VERSION" + else + nvm install "$REQUIRED_NODE_VERSION" + nvm use "$REQUIRED_NODE_VERSION" + fi + + # Now, check that the node version is correct, on all systems + + # Note: On windows, `nvm use` and `nvm install` always return success. + # https://github.com/coreybutler/nvm-windows/issues/738 + + # note the 'v' prefix that node emits (and npm doesn't!) + local CURRENT_NODE_VERSION="$(node --version)" + if [[ "$CURRENT_NODE_VERSION" != "v$REQUIRED_NODE_VERSION" ]]; then + builder_die "Attempted to select node.js version $REQUIRED_NODE_VERSION but found $CURRENT_NODE_VERSION instead" + fi +}