diff --git a/right/src/macro_events.c b/right/src/macro_events.c index b36711a55..38c7d3718 100644 --- a/right/src/macro_events.c +++ b/right/src/macro_events.c @@ -5,6 +5,7 @@ #include "macro_events.h" #include "config_parser/parse_macro.h" #include "macros/core.h" +#include "macros/status_buffer.h" #include "keymap.h" #include "led_display.h" #include "debug.h" @@ -256,3 +257,92 @@ void MacroEvent_ProcessJoinSplitEvents(merge_sensor_state_t currentlyJoined) previousEventMacroSlot = 255; } } + +static void validateLayerToken(const char* tokStart, const char* end) { + Macros_ConsumeLayerId(&(parser_context_t){.at = tokStart, .end = end}); +} + +static void validateOneEventName(const char* name, const char* nameEnd) +{ + const char* arg1 = NextTok(name, nameEnd); + + bool noArgs = TokenMatches(name, nameEnd, "$onInit") + || TokenMatches(name, nameEnd, "$onCapsLockStateChange") + || TokenMatches(name, nameEnd, "$onNumLockStateChange") + || TokenMatches(name, nameEnd, "$onScrollLockStateChange") + || TokenMatches(name, nameEnd, "$onJoin") + || TokenMatches(name, nameEnd, "$onSplit") + || TokenMatches(name, nameEnd, "$onError"); + if (noArgs) { + if (arg1 != nameEnd) { + Macros_ReportError("Macro event takes no arguments:", name, nameEnd); + } + return; + } + + if (TokenMatches(name, nameEnd, "$onKeymapChange")) { + if (arg1 == nameEnd) { + Macros_ReportError("$onKeymapChange requires or 'any':", name, nameEnd); + return; + } + return; + } + + if (TokenMatches(name, nameEnd, "$onKeymapLayerChange")) { + if (arg1 == nameEnd) { + Macros_ReportError("$onKeymapLayerChange requires :", name, nameEnd); + return; + } + const char* arg2 = NextTok(arg1, nameEnd); + if (arg2 == nameEnd) { + Macros_ReportError("$onKeymapLayerChange requires a layer argument:", name, nameEnd); + return; + } + validateLayerToken(arg2, nameEnd); + if (Macros_ParserError) { + return; + } + if (NextTok(arg2, nameEnd) != nameEnd) { + Macros_ReportError("$onKeymapLayerChange takes exactly two arguments:", name, nameEnd); + } + return; + } + + if (TokenMatches(name, nameEnd, "$onLayerChange")) { + if (arg1 == nameEnd) { + Macros_ReportError("$onLayerChange requires 'any' or a layer:", name, nameEnd); + return; + } + if (!TokenMatches(arg1, nameEnd, "any")) { + validateLayerToken(arg1, nameEnd); + if (Macros_ParserError) { + return; + } + } + if (NextTok(arg1, nameEnd) != nameEnd) { + Macros_ReportError("$onLayerChange takes a single argument:", name, nameEnd); + } + return; + } + + Macros_ReportError("Unknown smart macro event:", name, nameEnd); +} + +void MacroEvent_ValidateEventNames(void) +{ + bool oldParserStatus = Macros_ParserError; + + for (int i = 0; i < AllMacrosCount; i++) { + const char *thisName, *thisNameEnd; + FindMacroName(&AllMacros[i], &thisName, &thisNameEnd); + + if (thisName == thisNameEnd || *thisName != '$') { + continue; + } + + Macros_ParserError = false; + validateOneEventName(thisName, thisNameEnd); + } + + Macros_ParserError = oldParserStatus; +} diff --git a/right/src/macro_events.h b/right/src/macro_events.h index b306c0419..15846969e 100644 --- a/right/src/macro_events.h +++ b/right/src/macro_events.h @@ -36,5 +36,6 @@ void MacroEvent_ProcessStateKeyEvents(); void MacroEvent_ProcessJoinSplitEvents(merge_sensor_state_t currentlyJoined); void MacroEvent_TriggerGenericEvent(generic_macro_event_t eventId); + void MacroEvent_ValidateEventNames(void); #endif diff --git a/right/src/macros/core.c b/right/src/macros/core.c index 4b2118c4f..96f98e9d9 100644 --- a/right/src/macros/core.c +++ b/right/src/macros/core.c @@ -2,6 +2,7 @@ #include "config_parser/parse_macro.h" #include "debug.h" #include "event_scheduler.h" +#include "macro_events.h" #include "key_history.h" #include "keymap.h" #include "layer_stack.h" @@ -600,6 +601,8 @@ void Macros_ValidateAllMacros() Macros_ValidateMacro(macroIndex, 0, 255, 255, 255, 255); } + MacroEvent_ValidateEventNames(); + uint32_t t2 = Timer_GetCurrentTime(); LogU("Validation completed in %d ms!\n", t2 - t1); Macros_ValidationInProgress = false;