Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions right/src/macros/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,16 @@ void Macros_ValidateMacro(uint8_t macroIndex, uint16_t argumentOffset, uint8_t m
bool macroHasNotEnded = AllMacros[macroIndex].macroActionsCount;
while (macroHasNotEnded) {
if (S->ms.currentMacroAction.type == MacroActionType_Command) {
processCurrentMacroAction();
wasValid &= !Macros_ParserError;
Macros_ParserError = false;
// Skip validation of commands containing macroArg when no argument context is available
const char* cmdText = S->ms.currentMacroAction.cmd.text;
const char* cmdEnd = cmdText + S->ms.currentMacroAction.cmd.textLen;
bool skipCommand = argumentOffset == 0 && StrContains(cmdText, cmdEnd, "macroArg");

if (!skipCommand) {
processCurrentMacroAction();
wasValid &= !Macros_ParserError;
Macros_ParserError = false;
}
}

macroHasNotEnded = loadNextCommand() || loadNextAction();
Expand All @@ -535,21 +542,30 @@ void Macros_ValidateMacro(uint8_t macroIndex, uint16_t argumentOffset, uint8_t m

/**
* Current known limitations:
* - We check only actions that have arguments, therefore we don't catch missing arguments.
* - The validation takes hundreds of milliseconds, causing a short freeze when config is saved.
*/
void Macros_ValidateAllMacros()
{
macro_state_t* oldS = S;
scheduler_state_t schedulerState = Macros_SchedulerState;
memset(&Macros_SchedulerState, 0, sizeof Macros_SchedulerState);
LogU("Validating macros with arguments...\n");
Macros_DryRun = true;
Macros_ValidationInProgress = true;
uint32_t t1 = Timer_GetCurrentTime();

// Validate macros in binding site contexts (with arguments)
LogU("Validating macros with arguments...\n");
for (uint8_t keymapIndex = 0; keymapIndex < AllKeymapsCount; keymapIndex++) {
DryParseKeymap(keymapIndex);
}

// Validate all macros in general context (without arguments)
// Commands containing macroArg are skipped when argumentOffset == 0
LogU("Validating macros in general context...\n");
for (uint8_t macroIndex = 0; macroIndex < AllMacrosCount; macroIndex++) {
Macros_ValidateMacro(macroIndex, 0, 255, 255, 255, 255);
}

uint32_t t2 = Timer_GetCurrentTime();
LogU("Validation completed in %d ms!\n", t2 - t1);
Macros_ValidationInProgress = false;
Expand Down
24 changes: 24 additions & 0 deletions right/src/str_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,30 @@ const char* FindChar(char c, const char* str, const char* strEnd)
return strEnd;
}

bool StrContains(const char* str, const char* strEnd, const char* needle)
{
uint8_t needleLen = strlen(needle);
uint16_t strLen = strEnd - str;

if (strLen < needleLen) {
return false;
}

for (uint16_t i = 0; i <= strLen - needleLen; i++) {
bool match = true;
for (uint8_t j = 0; j < needleLen; j++) {
if (str[i + j] != needle[j]) {
match = false;
break;
}
}
if (match) {
return true;
}
}
return false;
}

static bool isEnd(parser_context_t* ctx) {
if (ctx->at < ctx->end) {
return false;
Expand Down
1 change: 1 addition & 0 deletions right/src/str_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
bool StrLessOrEqual(const char* a, const char* aEnd, const char* b, const char* bEnd);
bool StrEqual(const char* a, const char* aEnd, const char* b, const char* bEnd);
const char* FindChar(char c, const char* str, const char* strEnd);
bool StrContains(const char* str, const char* strEnd, const char* needle);
bool ConsumeToken(parser_context_t* ctx, const char *b);
void ConsumeAnyToken(parser_context_t* ctx);
void ConsumeCommentsAsWhite(bool consume);
Expand Down