diff options
Diffstat (limited to 'glcdskin/function.c')
-rw-r--r-- | glcdskin/function.c | 87 |
1 files changed, 66 insertions, 21 deletions
diff --git a/glcdskin/function.c b/glcdskin/function.c index 8582ad5..a2d58ca 100644 --- a/glcdskin/function.c +++ b/glcdskin/function.c @@ -22,7 +22,7 @@ namespace GLCD static const char * Internals[] = { - "not", "and", "or", "equal", "gt", "lt", "ge", "le", "ne", "file", "trans", + "not", "and", "or", "equal", "eq", "gt", "lt", "ge", "le", "ne", "file", "trans", "add", "sub", "mul", "div", "FontTotalWidth", "FontTotalHeight", @@ -33,6 +33,7 @@ static const char * Internals[] = "FontTextHeight", "ImageWidth", "ImageHeight", + "QueryFeature", NULL }; @@ -74,7 +75,7 @@ cSkinFunction::~cSkinFunction() delete mParams[i]; } -bool cSkinFunction::Parse(const std::string & Text) +bool cSkinFunction::Parse(const std::string & Text, bool reparse) { const char *text = Text.c_str(); const char *ptr = text, *last = text; @@ -89,7 +90,8 @@ bool cSkinFunction::Parse(const std::string & Text) || (*ptr == '\'' && *(ptr + strlen(ptr) - 1) != '\'') || (*ptr == '{' && *(ptr + strlen(ptr) - 1) != '}')) { - syslog(LOG_ERR, "ERROR: Unmatched string end\n"); + if (!reparse) // only log this error when not reparsing + syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unmatched string end\n"); return false; } @@ -113,7 +115,8 @@ bool cSkinFunction::Parse(const std::string & Text) // must be a variable id if (strlen(ptr) < 2) { - syslog(LOG_ERR, "ERROR: No variable id given\n"); + if (!reparse) // only log this error when not reparsing + syslog(LOG_ERR, "ERROR: graphlcd/skin/function: No variable id given\n"); return false; } @@ -127,7 +130,8 @@ bool cSkinFunction::Parse(const std::string & Text) int num = strtol(ptr, &end, 10); if (end == ptr || *end != '\0') { - syslog(LOG_ERR, "ERROR: Invalid numeric value\n"); + // don't log this because when parsing a string starting with a digit (eg: 0%) this may result in a load of false positives + //syslog(LOG_ERR, "ERROR: Invalid numeric value (%s)\n", Text.c_str()); return false; } @@ -136,9 +140,17 @@ bool cSkinFunction::Parse(const std::string & Text) } else { + bool inToken = false; + // expression for (; *ptr; ++ptr) { + + if (*ptr == '{') + inToken = true; + else if (inToken && *ptr == '}') + inToken = false; + if (*ptr == '(') { if (inExpr++ == 0) @@ -156,17 +168,19 @@ bool cSkinFunction::Parse(const std::string & Text) if (Internals[i] == NULL) { - syslog(LOG_ERR, "ERROR: Unknown function %.*s", (int)(ptr - last), last); + if (!reparse) // only log this error when not reparsing + syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unknown function %.*s", (int)(ptr - last), last); return false; } last = ptr + 1; } } - else if (*ptr == ',' || *ptr == ')') + else if ( ( (!inToken) && (*ptr == ',') ) || *ptr == ')') { if (inExpr == 0) { - syslog(LOG_ERR, "ERROR: Unmatched '%c' in expression", *ptr); + if (!reparse) // only log this error when not reparsing + syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unmatched '%c' in expression (%s)", *ptr, Text.c_str()); return false; } @@ -181,8 +195,9 @@ bool cSkinFunction::Parse(const std::string & Text) if (mNumParams == MAXPARAMETERS) { - syslog(LOG_ERR, "ERROR: Too many parameters to function, maximum is %d", - MAXPARAMETERS); + if (!reparse) // only log this error when not reparsing + syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Too many parameters to function, maximum is %d", + MAXPARAMETERS); return false; } @@ -204,6 +219,7 @@ bool cSkinFunction::Parse(const std::string & Text) params = -1; break; + case fun_equal: case fun_eq: case fun_ne: case fun_gt: @@ -247,13 +263,17 @@ bool cSkinFunction::Parse(const std::string & Text) params = 1; break; + case funQueryFeature: + params = 1; + break; + default: break; } if (params != -1 && mNumParams != (uint32_t) params) { - syslog(LOG_ERR, "ERROR: Text2Skin: Wrong number of parameters to %s, " + syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Wrong number of parameters to %s, " "expecting %d", Internals[mType - INTERNAL], params); return false; } @@ -266,7 +286,9 @@ bool cSkinFunction::Parse(const std::string & Text) if (inExpr > 0) { - syslog(LOG_ERR, "ERROR: Expecting ')' in expression"); + // only log this error when not reparsing + if (!reparse) + syslog(LOG_ERR, "ERROR: Expecting ')' in expression"); return false; } } @@ -345,8 +367,21 @@ cType cSkinFunction::Evaluate(void) const case variable: { cSkinVariable * variable = mSkin->GetVariable(mVariableId); - if (variable) - return variable->Value(); + if (variable) { + cType rv = variable->Value(); + if (rv.IsString()) { + std::string val = rv; + if (val.find("{") != std::string::npos || val.find("#") != std::string::npos) { + cSkinString *result = new cSkinString(mObject, false); + if (result->Parse(val)) { + val = (std::string) result->Evaluate(); + rv = cType(val); + } + delete result; + } + } + return rv; + } return false; } @@ -369,23 +404,24 @@ cType cSkinFunction::Evaluate(void) const } return false; + case fun_equal: case fun_eq: - return mParams[0]->Evaluate() == mParams[1]->Evaluate(); + return (std::string) mParams[0]->Evaluate() == (std::string) mParams[1]->Evaluate(); case fun_ne: - return mParams[0]->Evaluate() != mParams[1]->Evaluate(); + return (std::string) mParams[0]->Evaluate() != (std::string) mParams[1]->Evaluate(); case fun_gt: - return mParams[0]->Evaluate() > mParams[1]->Evaluate(); + return (int) mParams[0]->Evaluate() > (int) mParams[1]->Evaluate(); case fun_lt: - return mParams[0]->Evaluate() < mParams[1]->Evaluate(); + return (int) mParams[0]->Evaluate() < (int) mParams[1]->Evaluate(); case fun_ge: - return mParams[0]->Evaluate() >= mParams[1]->Evaluate(); + return (int) mParams[0]->Evaluate() >= (int) mParams[1]->Evaluate(); case fun_le: - return mParams[0]->Evaluate() <= mParams[1]->Evaluate(); + return (int) mParams[0]->Evaluate() <= (int) mParams[1]->Evaluate(); case fun_file: return FunFile(mParams[0]->Evaluate()); @@ -443,9 +479,18 @@ cType cSkinFunction::Evaluate(void) const case funImageHeight: return FunImage(mType, mParams[0]->Evaluate()); + case funQueryFeature: { + int value; + if (mSkin->Config().GetDriver()->GetFeature((const std::string)(mParams[0]->Evaluate()), value)) { + return (value) ? true : false; + } else { + return false; + } + } + default: //Dprintf("unknown function code\n"); - syslog(LOG_ERR, "ERROR: Unknown function code called (this shouldn't happen)"); + syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unknown function code called (this shouldn't happen)"); break; } return false; |