Fix logic error in eval_tokens and add debug output

When faced with sub-expressions, the parser was not correctly advancing
its iterator to the sub-expression's matching end parenthesis, causing
it to evaluate inner conditions twice, and incorrectly terminate early
when it reached the first end parenthesis.

Added preprocessor flag NOTIFO_DEBUG to generate debug output to
PutModule() to validate the expression parsing logic.
This commit is contained in:
John Reese 2011-02-15 10:18:13 -05:00
parent a855fe7eb5
commit a70ff4a364
1 changed files with 47 additions and 2 deletions

View File

@ -25,6 +25,15 @@
#define NOTIFO_AWAY
#endif
// Debug output
#define NOTIFO_DEBUG 0
#if NOTIFO_DEBUG
#define PutDebug(s) PutModule(s)
#else
#define PutDebug(s) //s
#endif
class CNotifoMod : public CModule
{
protected:
@ -195,10 +204,17 @@ class CNotifoMod : public CModule
VCString tokens;
padded.Split(" ", tokens, false);
return eval_tokens(tokens.begin(), tokens.end(), context, nick, message);
PutDebug("Evaluating message: <" + nick.GetNick() + "> " + message);
bool result = eval_tokens(tokens.begin(), tokens.end(), context, nick, message);
return result;
}
#define expr(x, y) else if (token == x) { value = oper ? value && y : value || y; }
#define expr(x, y) else if (token == x) { \
bool result = y; \
dbg += CString(x) + "/" + CString(result ? "true" : "false") + " "; \
value = oper ? value && result : value || result; \
}
/**
* Evaluate a tokenized boolean expression, or sub-expression.
@ -215,26 +231,54 @@ class CNotifoMod : public CModule
bool oper = true;
bool value = true;
CString dbg = "";
for(; pos != end; pos++)
{
CString token = pos->AsLower();
if (token == "(")
{
// recursively evaluate sub-expressions
bool inner = eval_tokens(++pos, end, context, nick, message);
dbg += "( inner/" + CString(inner ? "true" : "false") + " ) ";
value = oper ? value && inner : value || inner;
// search ahead to the matching parenthesis token
unsigned int parens = 1;
while(pos != end)
{
if (*pos == "(")
{
parens++;
}
else if (*pos == ")")
{
parens--;
}
if (parens == 0)
{
break;
}
pos++;
}
}
else if (token == ")")
{
pos++;
PutDebug(dbg);
return value;
}
else if (token == "and")
{
dbg += "and ";
oper = true;
}
else if (token == "or")
{
dbg += "or ";
oper = false;
}
@ -255,6 +299,7 @@ class CNotifoMod : public CModule
}
}
PutDebug(dbg);
return value;
}