Skip to content

Commit

Permalink
Revert "Revert "Fix elseif & Add if-elseif-else nesting levels""
Browse files Browse the repository at this point in the history
This reverts commit a4fe8d4.
  • Loading branch information
TD-er committed Sep 21, 2018
1 parent 9a39013 commit 07511fe
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 62 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ lib/readme.txt
src/Custom.h
/ESPEasy
test/output_export.cpp
.vscode
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
2 changes: 2 additions & 0 deletions src/ESPEasy-Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@
#define RULESETS_MAX 4
#define RULES_BUFFER_SIZE 64
#define NAME_FORMULA_LENGTH_MAX 40
#define RULES_IF_MAX_NESTING_LEVEL 4

#define UDP_PACKETSIZE_MAX 2048

#define PIN_MODE_UNDEFINED 0
Expand Down
179 changes: 117 additions & 62 deletions src/Misc.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2136,10 +2136,10 @@ String rulesProcessingFile(String fileName, String& event)
bool match = false;
bool codeBlock = false;
bool isCommand = false;
bool conditional = false;
bool condition = false;
bool ifBranche = false;
bool ifBrancheJustMatch = false;
bool condition[RULES_IF_MAX_NESTING_LEVEL];
bool ifBranche[RULES_IF_MAX_NESTING_LEVEL];
byte ifBlock = 0;
byte fakeIfBlock = 0;

byte buf[RULES_BUFFER_SIZE];
int len = 0;
Expand All @@ -2162,8 +2162,8 @@ String rulesProcessingFile(String fileName, String& event)
parseCompleteNonCommentLine(
line, event, log,
match, codeBlock, isCommand,
conditional, condition,
ifBranche, ifBrancheJustMatch);
condition, ifBranche,
ifBlock, fakeIfBlock);
backgroundtasks();
}

Expand All @@ -2184,10 +2184,11 @@ void parseCompleteNonCommentLine(
bool& match,
bool& codeBlock,
bool& isCommand,
bool& conditional,
bool& condition,
bool& ifBranche,
bool& ifBrancheJustMatch) {
bool condition[],
bool ifBranche[],
byte& ifBlock,
byte& fakeIfBlock)
{
isCommand = true;

// Strip comments
Expand All @@ -2199,6 +2200,23 @@ void parseCompleteNonCommentLine(
// only parse [xxx#yyy] if we have a matching ruleblock or need to eval the "on" (no codeBlock)
// This to avoid waisting CPU time...
line = parseTemplate(line, line.length());

if (match && !fakeIfBlock) {
// substitution of %eventvalue% is made here so it can be used on if statement too
if (event.charAt(0) == '!')
{
line.replace(F("%eventvalue%"), event); // substitute %eventvalue% with literal event string if starting with '!'
}
else
{
int equalsPos = event.indexOf("=");
if (equalsPos > 0)
{
String tmpString = event.substring(equalsPos + 1);
line.replace(F("%eventvalue%"), tmpString); // substitute %eventvalue% with the actual value from the event
}
}
}
}
line.trim();

Expand All @@ -2213,6 +2231,8 @@ void parseCompleteNonCommentLine(
{
if (line.startsWith(F("on ")))
{
ifBlock = 0;
fakeIfBlock = 0;
line = line.substring(3);
int split = line.indexOf(F(" do"));
if (split != -1)
Expand Down Expand Up @@ -2249,6 +2269,8 @@ void parseCompleteNonCommentLine(
isCommand = false;
codeBlock = false;
match = false;
ifBlock = 0;
fakeIfBlock = 0;
}

if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){
Expand All @@ -2265,8 +2287,8 @@ void parseCompleteNonCommentLine(
processMatchedRule(
lcAction, action, event, log,
match, codeBlock, isCommand,
conditional, condition,
ifBranche, ifBrancheJustMatch);
condition, ifBranche,
ifBlock, fakeIfBlock);
}
}

Expand All @@ -2275,70 +2297,101 @@ void processMatchedRule(
bool& match,
bool& codeBlock,
bool& isCommand,
bool& conditional,
bool& condition,
bool& ifBranche,
bool& ifBrancheJustMatch)
bool condition[],
bool ifBranche[],
byte& ifBlock,
byte& fakeIfBlock)
{
int split = lcAction.indexOf(F("if ")); // check for optional "if" condition
if (!lcAction.startsWith(F("elseif "))) {
if (split != -1)
{ // There is some 'if ' in the string.
conditional = true;
String check = lcAction.substring(split + 3);

log = F("[if ");
log += check;
log += F("]=");
condition = ifBrancheJustMatch == false && conditionMatchExtended(check);
if(condition == true)
if (fakeIfBlock)
isCommand = false;
else if (ifBlock)
if (condition[ifBlock-1] != ifBranche[ifBlock-1])
isCommand = false;
int split = lcAction.indexOf(F("elseif ")); // check for optional "elseif" condition
if (split != -1)
{
isCommand = false;
if (ifBlock && !fakeIfBlock)
{
if (ifBranche[ifBlock-1])
{
ifBrancheJustMatch = true;
if (condition[ifBlock-1])
ifBranche[ifBlock-1] = false;
else
{
String check = lcAction.substring(split + 7);
log = F("Lev.");
log += String(ifBlock);
log += F(": [elseif ");
log += check;
log += "]=";
condition[ifBlock-1] = conditionMatchExtended(check);
log += toString(condition[ifBlock-1]);
addLog(LOG_LEVEL_DEBUG, log);
}
}
ifBranche = true;
isCommand = false;
log += toString(condition);
addLog(LOG_LEVEL_DEBUG, log);
}
}
else
{ // Starts with 'elseif '
String check = lcAction.substring(7);
log = F("[elseif ");
log += check;
log += "]=";
condition = ifBrancheJustMatch == false && conditionMatchExtended(check);
if(condition == true)
{
split = lcAction.indexOf(F("if ")); // check for optional "if" condition
if (split != -1)
{
ifBrancheJustMatch = true;
if (ifBlock < RULES_IF_MAX_NESTING_LEVEL)
{
if (isCommand)
{
ifBlock++;
String check = lcAction.substring(split + 3);
log = F("Lev.");
log += String(ifBlock);
log += F(": [if ");
log += check;
log += F("]=");
condition[ifBlock-1] = conditionMatchExtended(check);
ifBranche[ifBlock-1] = true;
log += toString(condition[ifBlock-1]);
addLog(LOG_LEVEL_DEBUG, log);
}
else
fakeIfBlock++;
}
else
{
fakeIfBlock++;
log = F("Lev.");
log += String(ifBlock);
log = F(": Error: IF Nesting level exceeded!");
addLog(LOG_LEVEL_ERROR, log);
}
isCommand = false;
}
ifBranche = true;
isCommand = false;
log += toString(condition);
addLog(LOG_LEVEL_DEBUG, log);
}

if (lcAction == "else") // in case of an "else" block of actions, set ifBranche to false
if ((lcAction == F("else")) && !fakeIfBlock) // in case of an "else" block of actions, set ifBranche to false
{
ifBranche = false;
ifBranche[ifBlock-1] = false;
isCommand = false;
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String log = F("else = ");
log += toString(conditional && (condition == ifBranche));
log = F("Lev.");
log += String(ifBlock);
log += F(": [else]=");
log += toString(condition[ifBlock-1] == ifBranche[ifBlock-1]);
addLog(LOG_LEVEL_DEBUG, log);
}
}

if (lcAction == "endif") // conditional block ends here
if (lcAction == F("endif")) // conditional block ends here
{
conditional = false;
if (fakeIfBlock)
fakeIfBlock--;
else if (ifBlock)
ifBlock--;
isCommand = false;
ifBranche = false;
ifBrancheJustMatch = false;
}

// process the action if it's a command and unconditional, or conditional and the condition matches the if or else block.
if (isCommand && ((!conditional) || (conditional && (condition == ifBranche))))
if (isCommand)
{
if (event.charAt(0) == '!')
{
Expand Down Expand Up @@ -2415,19 +2468,21 @@ boolean ruleMatch(String& event, String& rule)
// Special handling of literal string events, they should start with '!'
if (event.charAt(0) == '!')
{
int pos = rule.indexOf('#');
if (pos == -1) // no # sign in rule, use 'wildcard' match on event 'source'
{
tmpEvent = event.substring(0,rule.length());
tmpRule = rule;
}

pos = rule.indexOf('*');
int pos = rule.indexOf('*');
if (pos != -1) // a * sign in rule, so use a'wildcard' match on message
{
tmpEvent = event.substring(0,pos-1);
tmpRule = rule.substring(0,pos-1);
}
else
{
pos = rule.indexOf('#');
if (pos == -1) // no # sign in rule, use 'wildcard' match on event 'source'
{
tmpEvent = event.substring(0,rule.length());
tmpRule = rule;
}
}

if (tmpEvent.equalsIgnoreCase(tmpRule))
return true;
Expand Down

0 comments on commit 07511fe

Please sign in to comment.