diff options
author | lordjaxom <lordjaxom> | 2004-12-08 18:48:39 +0000 |
---|---|---|
committer | lordjaxom <lordjaxom> | 2004-12-08 18:48:39 +0000 |
commit | 5382d18d05d358bb1c313c642395e835aa44a6a0 (patch) | |
tree | 2b5ef58620b3640c5b21e8eafe92ee4b266b1d30 /xml/function.c | |
parent | eb2f2c9600e8f69788232582191b141002bcd522 (diff) | |
download | vdr-plugin-text2skin-5382d18d05d358bb1c313c642395e835aa44a6a0.tar.gz vdr-plugin-text2skin-5382d18d05d358bb1c313c642395e835aa44a6a0.tar.bz2 |
1.0-pre1v1.0-pre1
Diffstat (limited to 'xml/function.c')
-rw-r--r-- | xml/function.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/xml/function.c b/xml/function.c new file mode 100644 index 0000000..e6e321c --- /dev/null +++ b/xml/function.c @@ -0,0 +1,212 @@ +/* + * $Id: function.c,v 1.4 2004/12/08 18:47:37 lordjaxom Exp $ + */ + +#include "xml/function.h" +#include "render.h" +#include "common.h" +#include <vdr/tools.h> + +static const char *Internals[] = { + "not", "and", "or", "equal", "file", "trans", NULL +}; + +const std::string cxFunction::False = ""; +const std::string cxFunction::True = "1"; + +cxFunction::cxFunction(void): + mType(string), + mString(), + mNumber(0), + mNumParams(0) +{ +} + +cxFunction::cxFunction(const cxString &String): + mType(string), + mString(String), + mNumber(0), + mNumParams(0) +{ +} + +cxFunction::cxFunction(const cxFunction &Src): + mType(Src.mType), + mString(Src.mString), + mNumber(Src.mNumber), + mNumParams(Src.mNumParams) +{ + for (uint i = 0; i < mNumParams; ++i) + mParams[i] = new cxFunction(*Src.mParams[i]); +} + +cxFunction::~cxFunction() +{ + for (uint i = 0; i < mNumParams; ++i) + delete mParams[i]; +} + +bool cxFunction::Parse(const std::string &Text) +{ + const char *text = Text.c_str(); + const char *ptr = text, *last = text; + eType type = undefined_function; + int inExpr = 0; + cxFunction *expr; + + if (*ptr == '\'' || *ptr == '{') { + // must be string + if (strlen(ptr) < 2 + || (*ptr == '\'' && *(ptr + strlen(ptr) - 1) != '\'') + || (*ptr == '{' && *(ptr + strlen(ptr) - 1) != '}')) { + esyslog("ERROR: Unmatched string end\n"); + return false; + } + + std::string temp; + if (*ptr == '\'') + temp.assign(ptr + 1, strlen(ptr) - 2); + else + temp.assign(ptr); + + int pos = -1; + while ((pos = temp.find("\\'", pos + 1)) != -1) + temp.replace(pos, 1, "\'"); + + if (!mString.Parse(temp)) + return false; + + mType = string; + } + else { + // expression + for (; *ptr; ++ptr) { + if (*ptr == '(') { + if (inExpr++ == 0) { + int i; + for (i = 0; Internals[i] != NULL; ++i) { + if ((size_t)(ptr - last) == strlen(Internals[i]) + && memcmp(last, Internals[i], ptr - last) == 0){ + type = (eType)(INTERNAL + 1 + i); + break; + } + } + + if (Internals[i] == NULL) { + esyslog("ERROR: Unknown function %.*s", (int)(ptr - last), last); + return false; + } + last = ptr + 1; + } + } + else if (*ptr == ',' || *ptr == ')') { + if (inExpr == 0) { + esyslog("ERROR: Unmatched '%c' in expression", *ptr); + return false; + } + + if (inExpr == 1) { + expr = new cxFunction; + if (!expr->Parse(std::string(last, ptr - last))) { + delete expr; + return false; + } + + mType = type; + mParams[mNumParams++] = expr; + last = ptr + 1; + } + + if (*ptr == ')') { + if (inExpr == 1) { + int params = 0; + + switch (mType) { + case fun_and: + case fun_or: params = -1; break; + + case fun_eq: ++params; + case fun_not: + case fun_trans: + case fun_file: ++params; + default: break; + } + + if (params != -1 && mNumParams != (uint)params) { + esyslog("ERROR: Text2Skin: Wrong number of parameters to %s, " + "expecting %d", Internals[mType - 1 - INTERNAL], params); + return false; + } + } + + --inExpr; + } + } + } + + if (inExpr > 0) { + esyslog("ERROR: Expecting ')' in expression"); + return false; + } + } + + return true; +} + +const std::string &cxFunction::FunFile(const std::string &Param) const +{ + std::string path = cText2SkinRender::ImagePath(Param); + Dprintf("checking file(%s)\n", path.c_str()); + if (access(path.c_str(), F_OK) == 0) + return Param; + return False; +} + +std::string cxFunction::Evaluate(void) const +{ + switch (mType) { + case string: + return mString.Evaluate(); + + case fun_not: + return mParams[0]->EvaluateToBool() ? False : True; + + case fun_and: + for (uint i = 0; i < mNumParams; ++i) { + if (!mParams[i]->EvaluateToBool()) + return False; + } + return True; + + case fun_or: + for (uint i = 0; i < mNumParams; ++i) { + if (mParams[i]->EvaluateToBool()) + return True; + } + return False; + + case fun_eq: + return mParams[0]->Evaluate() == mParams[1]->Evaluate() ? True : False; + + case fun_file: + return FunFile(mParams[0]->Evaluate()); + + case fun_trans: + return tr(mParams[0]->Evaluate().c_str()); + + default: + Dprintf("unknown function code\n"); + esyslog("ERROR: Unknown function code called (this shouldn't happen)"); + break; + } + return False; +} + +bool cxFunction::EvaluateToBool(void) +{ + std::string result = Evaluate(); + if (result == False/* || result == "0"*/) + return false; + return true; +} + |