File indexing completed on 2024-04-21 12:25:43

0001 /*
0002     This file belong to the KMPlayer project, a movie player plugin for Konqueror
0003     SPDX-FileCopyrightText: 2009 Koos Vriezen <koos.vriezen@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include <cstdio>
0009 #include <cassert>
0010 #include <cstdlib>
0011 #include <cstring>
0012 #include <ctime>
0013 #include <QUrl>
0014 #include "expression.h"
0015 
0016 #include <QRegExp>
0017 
0018 using namespace KMPlayer;
0019 
0020 QString NodeValue::value () const {
0021     if (attr)
0022         return attr->value ();
0023     if (node)
0024         return node->nodeValue ();
0025     return string;
0026 }
0027 
0028 namespace KMPlayer {
0029 
0030 struct ExprIterator {
0031     ExprIterator(ExprIterator* p) : cur_value(nullptr, nullptr), parent(p), position(0)
0032     {}
0033     virtual ~ExprIterator() {
0034         delete parent;
0035     }
0036     bool atEnd() const { return !cur_value.node && cur_value.string.isNull(); }
0037     virtual void next();
0038     NodeValue& current() { return cur_value; }
0039 
0040     NodeValue cur_value;
0041     ExprIterator* parent;
0042     int position;
0043 private:
0044     ExprIterator(const ExprIterator& p);
0045 };
0046 
0047 }
0048 
0049 Expression::iterator::~iterator() {
0050     delete iter;
0051 }
0052 
0053 void ExprIterator::next() {
0054     assert(!atEnd());
0055     cur_value = NodeValue(nullptr, nullptr);
0056     ++position;
0057 }
0058 
0059 Expression::iterator& Expression::iterator::operator =(const Expression::iterator& it) {
0060     if (iter != it.iter) {
0061         delete iter;
0062         iter = it.iter;
0063         it.iter = nullptr;
0064     }
0065     return *this;
0066 }
0067 
0068 bool Expression::iterator::operator ==(const Expression::iterator& it) const {
0069     if (iter == it.iter)
0070         return true;
0071     if (iter && it.iter)
0072         return iter->cur_value == it.iter->cur_value;
0073     if (!iter)
0074         return it.iter->atEnd();
0075     if (!it.iter)
0076         return iter->atEnd();
0077     return false;
0078 }
0079 
0080 Expression::iterator& Expression::iterator::operator ++() {
0081     if (iter && !iter->atEnd())
0082         iter->next();
0083     return *this;
0084 }
0085 
0086 NodeValue& Expression::iterator::operator*() {
0087     static NodeValue empty(nullptr, nullptr);
0088     if (iter)
0089         return iter->current();
0090     return empty;
0091 }
0092 
0093 NodeValue* Expression::iterator::operator->() {
0094     if (iter)
0095         return &iter->cur_value;
0096     return nullptr;
0097 }
0098 
0099 namespace {
0100 
0101 struct EvalState {
0102     EvalState (EvalState *p, const QString &root_tag=QString())
0103      : def_root_tag (root_tag), root (nullptr),
0104        iterator(nullptr), parent (p),
0105        sequence (1), ref_count (0) {}
0106 
0107     void addRef () { ++ref_count; }
0108     void removeRef () { if (--ref_count == 0) delete this; }
0109 
0110     QString def_root_tag;
0111     NodeValue root;
0112     ExprIterator* iterator;
0113     EvalState *parent;
0114     int sequence;
0115     int ref_count;
0116 };
0117 
0118 struct AST : public Expression {
0119     enum Type {
0120         TUnknown, TInteger, TBool, TFloat, TString, TSequence
0121     };
0122 
0123     AST (EvalState *ev);
0124     ~AST () override;
0125 
0126     bool toBool () const override;
0127     int toInt () const override;
0128     float toFloat () const override;
0129     QString toString () const override;
0130     virtual ExprIterator* exprIterator(ExprIterator* parent) const;
0131     iterator begin() const override;
0132     iterator end() const override;
0133     virtual Type type(bool calc) const;
0134     void setRoot (Node *root) override;
0135     void setRoot (const NodeValue &value);
0136 #ifdef KMPLAYER_EXPR_DEBUG
0137     virtual void dump () const;
0138 #endif
0139 
0140     mutable int sequence;
0141     mutable EvalState *eval_state;
0142     AST *first_child;
0143     AST *next_sibling;
0144 };
0145 
0146 struct BoolBase : public AST {
0147     BoolBase (EvalState *ev) : AST (ev), b (false) {}
0148 
0149     QString toString () const override;
0150     Type type(bool calc) const override;
0151 
0152     mutable bool b;
0153 };
0154 
0155 struct IntegerBase : public AST {
0156     IntegerBase (EvalState *ev) : AST (ev), i (0) {}
0157 
0158     float toFloat () const override;
0159     Type type(bool calc) const override;
0160 
0161     mutable int i;
0162 };
0163 
0164 struct Integer : public IntegerBase {
0165     Integer (EvalState *ev, int i_) : IntegerBase (ev) {
0166         i = i_;
0167     }
0168 
0169     int toInt () const override;
0170 #ifdef KMPLAYER_EXPR_DEBUG
0171     virtual void dump () const;
0172 #endif
0173 };
0174 
0175 struct Float : public AST {
0176     Float (EvalState *ev, float f_) : AST (ev), f (f_) {}
0177 
0178     bool toBool () const override { return false; }
0179     int toInt () const override { return (int) f; }
0180     float toFloat () const override { return f; }
0181     Type type(bool calc) const override;
0182 #ifdef KMPLAYER_EXPR_DEBUG
0183     virtual void dump () const {
0184         fprintf (stderr, "Float %f", f);
0185         AST::dump();
0186     }
0187 #endif
0188 
0189     float f;
0190 };
0191 
0192 struct StringBase : public AST {
0193     StringBase (EvalState *ev) : AST (ev) {}
0194     StringBase (EvalState *ev, const QString& s)
0195      : AST (ev), string(s) {}
0196 
0197     bool toBool () const override;
0198     int toInt () const override;
0199     float toFloat () const override;
0200     Type type(bool calc) const override;
0201 
0202     mutable QString string;
0203 };
0204 
0205 struct SequenceBase : public StringBase {
0206     SequenceBase (EvalState *ev) : StringBase (ev) {}
0207     SequenceBase (EvalState *ev, const QString& s)
0208         : StringBase (ev, s) {}
0209 
0210     bool toBool () const override;
0211     QString toString () const override;
0212     Type type(bool calc) const override;
0213 };
0214 
0215 struct Step : public SequenceBase {
0216     enum Axes {
0217         AncestorAxis=0x01, AttributeAxis=0x02, ChildAxis=0x04,
0218         DescendantAxis=0x08, FollowingAxis=0x10, FollowingSiblingAxis=0x20,
0219         NamespaceAxis=0x40, ParentAxis=0x80, PrecedingAxis=0x100,
0220         PrecedingSiblingAxis=0x200, SelfAxis=0x400
0221     };
0222     enum NodeType {
0223         AnyType, TextType, ElementType
0224     };
0225     Step (EvalState *ev, const QString &s, int ax, NodeType nt)
0226         : SequenceBase (ev, s)
0227         , axes(ax)
0228         , node_type(nt)
0229         , context_node(ax == SelfAxis && s.isEmpty())
0230     {}
0231     ExprIterator* exprIterator(ExprIterator* parent) const override;
0232     bool matches (Node *n) const;
0233     bool matches (Attribute *a) const;
0234 #ifdef KMPLAYER_EXPR_DEBUG
0235     virtual void dump () const {
0236         fprintf (stderr, "Step %c%s",
0237                 (axes & AttributeAxis) ? '@' : ' ',
0238                 context_node ? "." : string.toLatin1 ().constData ());
0239         AST::dump();
0240     }
0241 #endif
0242 
0243     int axes;
0244     NodeType node_type;
0245     bool context_node;
0246 };
0247 
0248 struct Path : public SequenceBase {
0249     Path (EvalState *ev, AST *steps, bool context)
0250         : SequenceBase (ev), start_contextual (context) {
0251         first_child = steps;
0252     }
0253 
0254     ExprIterator* exprIterator(ExprIterator* parent) const override;
0255 #ifdef KMPLAYER_EXPR_DEBUG
0256     virtual void dump () const {
0257         fprintf (stderr, "Path ");
0258         AST::dump();
0259     }
0260 #endif
0261     bool start_contextual;
0262 };
0263 
0264 struct PredicateFilter : public SequenceBase {
0265     PredicateFilter (EvalState *ev, AST *children) : SequenceBase (ev) {
0266         first_child = children;
0267     }
0268 
0269     ExprIterator* exprIterator(ExprIterator* parent) const override;
0270 #ifdef KMPLAYER_EXPR_DEBUG
0271     virtual void dump () const {
0272         fprintf (stderr, "Predicate ");
0273         first_child->dump();
0274         fprintf (stderr, "[");
0275         for (AST *n = first_child->next_sibling; n; n = n->next_sibling)
0276             n->dump();
0277         fprintf (stderr, "]");
0278     }
0279 #endif
0280 };
0281 
0282 struct StringLiteral : public StringBase {
0283     StringLiteral (EvalState *ev, const QString& s)
0284      : StringBase (ev, s) {}
0285 
0286     QString toString () const override;
0287     Type type(bool calc) const override;
0288 #ifdef KMPLAYER_EXPR_DEBUG
0289     virtual void dump () const {
0290         fprintf (stderr, "StringLiteral %s", string.toLatin1 ().constData ());
0291         AST::dump();
0292     }
0293 #endif
0294 };
0295 
0296 struct Boolean : public BoolBase {
0297     Boolean(EvalState *ev) : BoolBase(ev) {}
0298 
0299     bool toBool() const override;
0300 };
0301 
0302 struct Contains : public BoolBase {
0303     Contains (EvalState *ev) : BoolBase (ev) {}
0304 
0305     bool toBool () const override;
0306 };
0307 
0308 struct Not : public BoolBase {
0309     Not (EvalState *ev) : BoolBase (ev) {}
0310 
0311     bool toBool () const override;
0312 };
0313 
0314 struct StartsWith: public BoolBase {
0315     StartsWith (EvalState *ev) : BoolBase (ev) {}
0316 
0317     bool toBool () const override;
0318 };
0319 
0320 struct Count : public IntegerBase {
0321     Count (EvalState *ev) : IntegerBase (ev) {}
0322 
0323     int toInt () const override;
0324 };
0325 
0326 struct HoursFromTime : public IntegerBase {
0327     HoursFromTime (EvalState *ev) : IntegerBase (ev) {}
0328 
0329     int toInt () const override;
0330 };
0331 
0332 struct MinutesFromTime : public IntegerBase {
0333     MinutesFromTime (EvalState *ev) : IntegerBase (ev) {}
0334 
0335     int toInt () const override;
0336 };
0337 
0338 struct SecondsFromTime : public IntegerBase {
0339     SecondsFromTime (EvalState *ev) : IntegerBase (ev) {}
0340 
0341     int toInt () const override;
0342 };
0343 
0344 struct Last : public IntegerBase {
0345     Last (EvalState *ev) : IntegerBase (ev) {}
0346 
0347     int toInt () const override;
0348 };
0349 
0350 struct Number : public IntegerBase {
0351     Number (EvalState *ev) : IntegerBase (ev) {}
0352 
0353     int toInt () const override;
0354 };
0355 
0356 struct Position : public IntegerBase {
0357     Position (EvalState *ev) : IntegerBase (ev) {}
0358 
0359     int toInt () const override;
0360 };
0361 
0362 struct StringLength : public IntegerBase {
0363     StringLength (EvalState *ev) : IntegerBase (ev) {}
0364 
0365     int toInt () const override;
0366 };
0367 
0368 struct Concat : public StringBase {
0369     Concat (EvalState *ev) : StringBase (ev) {}
0370 
0371     QString toString () const override;
0372 };
0373 
0374 struct StringJoin : public StringBase {
0375     StringJoin (EvalState *ev) : StringBase (ev) {}
0376 
0377     QString toString () const override;
0378 };
0379 
0380 struct SubstringAfter : public StringBase {
0381     SubstringAfter (EvalState *ev) : StringBase (ev) {}
0382 
0383     QString toString () const override;
0384 };
0385 
0386 struct SubstringBefore : public StringBase {
0387     SubstringBefore (EvalState *ev) : StringBase (ev) {}
0388 
0389     QString toString () const override;
0390 };
0391 
0392 struct CurrentTime : public StringBase {
0393     CurrentTime (EvalState *ev) : StringBase (ev) {}
0394 
0395     QString toString () const override;
0396 };
0397 
0398 struct CurrentDate : public StringBase {
0399     CurrentDate (EvalState *ev) : StringBase (ev) {}
0400 
0401     QString toString () const override;
0402 };
0403 
0404 struct EscapeUri : public StringBase {
0405     EscapeUri (EvalState *ev) : StringBase (ev) {}
0406 
0407     QString toString () const override;
0408 };
0409 
0410 /*struct Sort : public SequenceBase {
0411     Sort (EvalState *ev) : SequenceBase (ev) {}
0412 
0413     virtual Sequence *toSequence () const;
0414 };*/
0415 
0416 struct SubSequence : public SequenceBase {
0417     SubSequence (EvalState *ev) : SequenceBase (ev) {}
0418 
0419     ExprIterator* exprIterator(ExprIterator* parent) const override;
0420 };
0421 
0422 struct Tokenize : public SequenceBase {
0423     Tokenize (EvalState *ev) : SequenceBase (ev) {}
0424 
0425     ExprIterator* exprIterator(ExprIterator* parent) const override;
0426 };
0427 
0428 struct Multiply : public AST {
0429     Multiply (EvalState *ev, AST *children) : AST (ev) {
0430         first_child = children;
0431     }
0432 
0433     int toInt () const override;
0434     float toFloat () const override;
0435     Type type(bool calc) const override;
0436 #ifdef KMPLAYER_EXPR_DEBUG
0437     virtual void dump () const;
0438 #endif
0439 };
0440 
0441 struct Divide : public AST {
0442     Divide (EvalState *ev, AST *children) : AST (ev) {
0443         first_child = children;
0444     }
0445 
0446     int toInt () const override;
0447     float toFloat () const override;
0448     Type type(bool calc) const override;
0449 #ifdef KMPLAYER_EXPR_DEBUG
0450     virtual void dump () const;
0451 #endif
0452 };
0453 
0454 struct Modulus : public AST {
0455     Modulus (EvalState *ev, AST *children) : AST (ev) {
0456         first_child = children;
0457     }
0458 
0459     int toInt () const override;
0460     float toFloat () const override;
0461     Type type(bool calc) const override;
0462 #ifdef KMPLAYER_EXPR_DEBUG
0463     virtual void dump () const;
0464 #endif
0465 };
0466 
0467 struct Plus : public AST {
0468     Plus (EvalState *ev, AST *children) : AST (ev) {
0469         first_child = children;
0470     }
0471 
0472     int toInt () const override;
0473     float toFloat () const override;
0474     Type type(bool calc) const override;
0475 #ifdef KMPLAYER_EXPR_DEBUG
0476     virtual void dump () const;
0477 #endif
0478 };
0479 
0480 struct Minus : public AST {
0481     Minus (EvalState *ev, AST *children) : AST (ev) {
0482         first_child = children;
0483     }
0484 
0485     int toInt () const override;
0486     float toFloat () const override;
0487     Type type(bool calc) const override;
0488 #ifdef KMPLAYER_EXPR_DEBUG
0489     virtual void dump () const;
0490 #endif
0491 };
0492 
0493 struct Join : public SequenceBase {
0494     Join (EvalState *ev, AST *children) : SequenceBase (ev) {
0495         first_child = children;
0496     }
0497 
0498     ExprIterator* exprIterator(ExprIterator* parent) const override;
0499 #ifdef KMPLAYER_EXPR_DEBUG
0500     virtual void dump () const;
0501 #endif
0502 };
0503 
0504 struct Comparison : public BoolBase {
0505     enum CompType {
0506         lt = 1, lteq, eq, noteq, gt, gteq, land, lor
0507     };
0508 
0509     Comparison (EvalState *ev, CompType ct, AST *children)
0510      : BoolBase (ev), comp_type (ct) {
0511         first_child = children;
0512     }
0513 
0514     bool toBool () const override;
0515 #ifdef KMPLAYER_EXPR_DEBUG
0516     virtual void dump () const;
0517 #endif
0518 
0519     CompType comp_type;
0520 };
0521 
0522 }
0523 
0524 
0525 AST::AST (EvalState *ev)
0526  : sequence (0), eval_state (ev), first_child (nullptr), next_sibling (nullptr) {
0527     ev->addRef ();
0528 }
0529 
0530 AST::~AST () {
0531     while (first_child) {
0532         AST *tmp = first_child;
0533         first_child = first_child->next_sibling;
0534         delete tmp;
0535     }
0536     eval_state->removeRef ();
0537 }
0538 
0539 bool AST::toBool () const {
0540     return toInt ();
0541 }
0542 
0543 int AST::toInt () const {
0544     return 0;
0545 }
0546 
0547 float AST::toFloat () const {
0548     return 0.0;
0549 }
0550 
0551 QString AST::toString () const {
0552     switch (type(false)) {
0553     case TBool:
0554         return toBool () ? "true" : "false";
0555     case TInteger:
0556         return QString::number (toInt ());
0557     case TFloat:
0558         return QString::number (toFloat ());
0559     default:
0560         return QString ();
0561     }
0562 }
0563 
0564 ExprIterator* AST::exprIterator(ExprIterator* parent) const {
0565     // beware of recursion w/ toString
0566     struct ValueIterator : public ExprIterator {
0567         ValueIterator(ExprIterator* p, const QString& s) : ExprIterator(p) {
0568             cur_value = NodeValue(s);
0569         }
0570     };
0571     return new ValueIterator(parent, toString());
0572 }
0573 
0574 Expression::iterator AST::begin() const {
0575     return iterator(exprIterator(nullptr));
0576 }
0577 
0578 Expression::iterator AST::end() const {
0579     return iterator();
0580 }
0581 
0582 AST::Type AST::type(bool) const {
0583     return TUnknown;
0584 }
0585 
0586 void AST::setRoot (Node *root) {
0587     setRoot (NodeValue (root));
0588 }
0589 
0590 void AST::setRoot (const NodeValue& value) {
0591     eval_state->root = value;
0592     eval_state->sequence++;
0593 }
0594 
0595 #ifdef KMPLAYER_EXPR_DEBUG
0596 void AST::dump () const {
0597     if (first_child) {
0598         fprintf (stderr, "[ ");
0599         for (AST *child = first_child; child; child = child->next_sibling) {
0600             if (child != first_child)
0601                 fprintf (stderr, ", ");
0602             child->dump();
0603         }
0604         fprintf (stderr, " ]");
0605     }
0606 }
0607 #endif
0608 
0609 static void appendASTChild (AST *p, AST *c) {
0610     if (!p->first_child)
0611         p->first_child = c;
0612     else
0613         for (AST *chld = p->first_child; chld; chld = chld->next_sibling)
0614             if (!chld->next_sibling) {
0615                 chld->next_sibling = c;
0616                 break;
0617             }
0618 }
0619 
0620 static AST *releaseASTChildren (AST *p) {
0621     AST *child = p->first_child;
0622     p->first_child = nullptr;
0623     return child;
0624 }
0625 
0626 static AST *releaseLastASTChild (AST *p) {
0627     AST **chldptr = &p->first_child;
0628     while ((*chldptr)->next_sibling)
0629         chldptr = &(*chldptr)->next_sibling;
0630     AST *last = *chldptr;
0631     *chldptr = nullptr;
0632     return last;
0633 }
0634 
0635 QString BoolBase::toString () const {
0636     return toBool () ? "true" : "false";
0637 }
0638 
0639 AST::Type BoolBase::type(bool) const {
0640     return TBool;
0641 }
0642 
0643 float IntegerBase::toFloat () const {
0644     return toInt ();
0645 }
0646 
0647 AST::Type IntegerBase::type(bool) const {
0648     return TInteger;
0649 }
0650 
0651 int Integer::toInt () const {
0652     return i;
0653 }
0654 
0655 #ifdef KMPLAYER_EXPR_DEBUG
0656 void Integer::dump () const {
0657     fprintf (stderr, "Integer %d", i);
0658     AST::dump();
0659 }
0660 #endif
0661 
0662 AST::Type Float::type(bool) const {
0663     return TFloat;
0664 }
0665 
0666 bool StringBase::toBool () const {
0667     QString s = toString ();
0668     if (s.toLower () == "true")
0669         return true;
0670     if (s.toLower () == "false")
0671         return false;
0672     return s.toInt ();
0673 }
0674 
0675 int StringBase::toInt () const {
0676     return toString ().toInt ();
0677 }
0678 
0679 float StringBase::toFloat () const {
0680     return toString ().toFloat ();
0681 }
0682 
0683 AST::Type StringBase::type(bool) const {
0684     return TString;
0685 }
0686 
0687 bool Step::matches (Node *n) const {
0688     if (string.isEmpty()) {
0689         if (AnyType == node_type)
0690             return true;
0691         if (ElementType == node_type)
0692             return n->isElementNode();
0693         if (TextType == node_type)
0694             return !strcmp("#text", n->nodeName());
0695     }
0696     return string == n->nodeName ();
0697 }
0698 
0699 bool Step::matches (Attribute *a) const {
0700     return string.isEmpty() || string == a->name ();
0701 }
0702 
0703 bool SequenceBase::toBool () const {
0704     bool b = false;
0705     if (eval_state->iterator) {
0706         ExprIterator* it = exprIterator(nullptr);
0707         b = !it->atEnd();
0708         delete it;
0709     } else {
0710         b = StringBase::toBool ();
0711     }
0712     return b;
0713 }
0714 
0715 QString SequenceBase::toString () const {
0716     if (eval_state->sequence != sequence) {
0717         string.clear();
0718         ExprIterator* it = exprIterator(nullptr);
0719         if (!it->atEnd()) {
0720             string = it->cur_value.value();
0721             while (!it->atEnd()) {
0722                 it->next();
0723             }
0724         }
0725         if (it->position != 1)
0726             string = QString::number(it->position);
0727         sequence = eval_state->sequence;
0728         delete it;
0729     }
0730     return string;
0731 }
0732 
0733 AST::Type SequenceBase::type(bool calc) const {
0734     if (calc) {
0735         QString s = toString ();
0736         if (s.toLower () == "true" ||
0737                 s.toLower () == "false")
0738             return TBool;
0739         bool ok;
0740         s.toInt (&ok);
0741         if (ok)
0742             return TInteger;
0743         s.toFloat (&ok);
0744         if (ok)
0745             return TFloat;
0746         return TString;
0747     }
0748     return TSequence;
0749 }
0750 
0751 ExprIterator* Step::exprIterator(ExprIterator* parent) const {
0752 
0753     struct ChildrenIterator : public ExprIterator {
0754         ChildrenIterator(ExprIterator* p) : ExprIterator(p) {
0755             pullNext();
0756         }
0757         void pullNext() {
0758             for (; !parent->atEnd(); parent->next())
0759                 if (parent->cur_value.node && parent->cur_value.node->firstChild()) {
0760                     cur_value = NodeValue(parent->cur_value.node->firstChild());
0761                     return;
0762                 }
0763             cur_value = NodeValue(nullptr, nullptr);
0764         }
0765         void next() override {
0766             assert(cur_value.node);
0767             cur_value.node = cur_value.node->nextSibling();
0768             if (!cur_value.node) {
0769                 parent->next();
0770                 pullNext();
0771             }
0772             ++position;
0773         }
0774     };
0775     struct SiblingIterator : public ExprIterator {
0776         const bool forward;
0777         SiblingIterator(ExprIterator* p, bool fw) : ExprIterator(p), forward(fw) {
0778             cur_value = p->cur_value;
0779             pullNext();
0780         }
0781         void pullNext() {
0782             while (!parent->atEnd()) {
0783                 if (forward && cur_value.node->nextSibling()) {
0784                     cur_value.node = cur_value.node->nextSibling();
0785                     return;
0786                 } else if (!forward && cur_value.node->previousSibling()) {
0787                     cur_value.node = cur_value.node->previousSibling();
0788                     return;
0789                 }
0790                 parent->next();
0791                 cur_value = parent->cur_value;
0792             }
0793             cur_value = NodeValue(nullptr, nullptr);
0794         }
0795         void next() override {
0796             assert(!atEnd());
0797             pullNext();
0798             ++position;
0799         }
0800     };
0801     struct DescendantIterator : public ChildrenIterator {
0802         DescendantIterator(ExprIterator* p) : ChildrenIterator(p)
0803         {}
0804         void next() override {
0805             assert(cur_value.node);
0806             if (cur_value.node->firstChild()) {
0807                 cur_value.node = cur_value.node->firstChild();
0808                 return;
0809             }
0810             if (cur_value.node->nextSibling()) {
0811                 cur_value.node = cur_value.node->nextSibling();
0812                 return;
0813             }
0814             for (Node* n = cur_value.node->parentNode(); n && n != parent->cur_value.node; n = n->parentNode())
0815                 if (n->nextSibling()) {
0816                     cur_value.node = n->nextSibling();
0817                     return;
0818                 }
0819             parent->next();
0820             pullNext();
0821             ++position;
0822         }
0823     };
0824     struct StepIterator : public ExprIterator {
0825         const Step* step;
0826 
0827         StepIterator(ExprIterator* p, const Step* s)
0828          : ExprIterator(p), step(s) {
0829             pullNext();
0830         }
0831         bool nextAttribute(Attribute *a) {
0832             for (; a; a = a->nextSibling ())
0833                 if (step->matches(a)) {
0834                     cur_value.attr = a;
0835                     return true;
0836                 }
0837             cur_value.attr = nullptr;
0838             return false;
0839         }
0840         void pullNext() {
0841             while (!parent->atEnd()) {
0842                 Node* n = parent->cur_value.node;
0843                 assert(n);
0844                 if (!n)
0845                     continue; //FIXME
0846                 if (step->axes & Step::AttributeAxis) {
0847                     if (n->isElementNode()) {
0848                         Element* e = static_cast<Element*>(n);
0849                         if (nextAttribute(e->attributes().first())) {
0850                             cur_value.node = n;
0851                             return;
0852                         }
0853                     }
0854                 } else if (step->matches(n)) {
0855                     cur_value.node = n;
0856                     return;
0857                 }
0858                 parent->next();
0859             }
0860             cur_value.node = nullptr;
0861         }
0862         void next() override {
0863             assert(!atEnd());
0864             if ((step->axes & Step::AttributeAxis)
0865                     && cur_value.attr
0866                     && nextAttribute(cur_value.attr->nextSibling())) {
0867                 ++position;
0868                 return;
0869             }
0870             parent->next();
0871             pullNext();
0872             ++position;
0873         }
0874     };
0875     if (context_node)
0876         return parent;
0877     ExprIterator* it = parent;
0878     if (axes & DescendantAxis)
0879         it = new DescendantIterator(parent);
0880     else if (axes & FollowingSiblingAxis || axes & PrecedingSiblingAxis)
0881         it = new SiblingIterator(parent, axes & FollowingSiblingAxis);
0882     else if (!(axes & AttributeAxis))
0883         it = new ChildrenIterator(parent);
0884     return new StepIterator(it, this);
0885 }
0886 
0887 ExprIterator* Path::exprIterator(ExprIterator* parent) const {
0888     struct PathIterator : public ExprIterator {
0889         bool contextual;
0890         PathIterator(ExprIterator* parent, NodeValue& c)
0891          : ExprIterator(parent), contextual(false) {
0892             cur_value = c;
0893         }
0894         void next() override {
0895             assert(!atEnd());
0896             if (!contextual || parent->atEnd()) {
0897                 cur_value = NodeValue(nullptr, nullptr);
0898             } else {
0899                 parent->next();
0900                 cur_value = parent->cur_value;
0901             }
0902             ++position;
0903         }
0904     };
0905 
0906     EvalState *es = eval_state;
0907     if (!start_contextual) {
0908         while (es->parent)
0909             es = es->parent;
0910     }
0911     ExprIterator* it = new PathIterator(parent, es->root);
0912     for (AST *s = first_child; s; s = s->next_sibling) {
0913         if (it->atEnd())
0914             return it;
0915         it = s->exprIterator(it);
0916     }
0917     return it;
0918 }
0919 
0920 ExprIterator* PredicateFilter::exprIterator(ExprIterator* parent) const {
0921     struct PredicateIterator : public ExprIterator {
0922         AST *ast;
0923         PredicateIterator(ExprIterator* parent, AST* a)
0924          : ExprIterator(parent), ast(a) {
0925             pullNext();
0926         }
0927         void pullNext() {
0928             while (!parent->atEnd()) {
0929                 //while (ast) {
0930                     ast->setRoot(parent->cur_value);
0931                     ast->eval_state->iterator = parent;
0932                     cur_value = parent->cur_value;
0933                     bool res = ast->toBool();
0934                     ast->eval_state->iterator = nullptr;
0935                     if (res) {
0936                         return;
0937                     }
0938                     //ast = ast->next_sibling;
0939                // }
0940                 if (parent->atEnd())
0941                     break;
0942                 parent->next();
0943             }
0944             cur_value = NodeValue(nullptr, nullptr);
0945         }
0946         void next() override {
0947             assert(!atEnd());
0948             parent->next();
0949             pullNext();
0950             ++position;
0951         }
0952     };
0953     if (!first_child)
0954         return parent;
0955     ExprIterator *it = first_child->exprIterator(parent); //step
0956     if (!first_child->next_sibling)
0957         return it;
0958     return new PredicateIterator(it, const_cast<AST*>(first_child)->next_sibling);
0959 }
0960 
0961 QString StringLiteral::toString () const {
0962     return string;
0963 }
0964 
0965 AST::Type StringLiteral::type(bool) const {
0966     return TString;
0967 }
0968 
0969 bool Boolean::toBool() const {
0970     if (eval_state->sequence != sequence) {
0971         sequence = eval_state->sequence;
0972         b = false;
0973         if (first_child) {
0974             switch (first_child->type(false)) {
0975             case TInteger:
0976             case TFloat:
0977                 b = first_child->toInt() != 0;
0978                 break;
0979             case TString:
0980                 b = !first_child->toString().isEmpty();
0981                 break;
0982             default:
0983                 b = first_child->toBool();
0984             }
0985         }
0986     }
0987     return b;
0988 }
0989 
0990 bool Contains::toBool () const {
0991     if (eval_state->sequence != sequence) {
0992         sequence = eval_state->sequence;
0993         b = false;
0994         if (first_child) {
0995             AST *s = first_child->next_sibling;
0996             if (s)
0997                 b = first_child->toString ().indexOf (s->toString ()) > -1;
0998         }
0999     }
1000     return b;
1001 }
1002 
1003 bool Not::toBool () const {
1004     if (eval_state->sequence != sequence) {
1005         sequence = eval_state->sequence;
1006         b = first_child ? !first_child->toBool () : true;
1007     }
1008     return b;
1009 }
1010 
1011 bool StartsWith::toBool () const {
1012     if (eval_state->sequence != sequence) {
1013         sequence = eval_state->sequence;
1014         b = false;
1015         if (first_child) {
1016             AST *s = first_child->next_sibling;
1017             if (s)
1018                 b = first_child->toString ().startsWith (s->toString ());
1019             else if (eval_state->parent)
1020                 b = eval_state->root.value ().startsWith (first_child->toString ());
1021         }
1022     }
1023     return b;
1024 }
1025 
1026 int Count::toInt () const {
1027     if (eval_state->sequence != sequence) {
1028         sequence = eval_state->sequence;
1029         i = 0;
1030         if (first_child) {
1031             ExprIterator* it = first_child->exprIterator(nullptr);
1032             while (!it->atEnd())
1033                 it->next();
1034             i = it->position;
1035             delete it;
1036         } else if (eval_state->iterator) {
1037             while (!eval_state->iterator->atEnd())
1038                 eval_state->iterator->next();
1039             i = eval_state->iterator->position;
1040         }
1041     }
1042     return i;
1043 }
1044 
1045 int HoursFromTime::toInt () const {
1046     if (eval_state->sequence != sequence) {
1047         if (first_child) {
1048             QString s = first_child->toString ();
1049             int p = s.indexOf (':');
1050             if (p > -1)
1051                 i = s.left (p).toInt ();
1052         }
1053         sequence = eval_state->sequence;
1054     }
1055     return i;
1056 }
1057 
1058 int MinutesFromTime::toInt () const {
1059     if (eval_state->sequence != sequence) {
1060         if (first_child) {
1061             QString s = first_child->toString ();
1062             int p = s.indexOf (':');
1063             if (p > -1) {
1064                 int q = s.indexOf (':', p + 1);
1065                 if (q > -1)
1066                     i = s.mid (p + 1, q - p - 1).toInt ();
1067             }
1068         }
1069         sequence = eval_state->sequence;
1070     }
1071     return i;
1072 }
1073 
1074 int SecondsFromTime::toInt () const {
1075     if (eval_state->sequence != sequence) {
1076         if (first_child) {
1077             QString s = first_child->toString ();
1078             int p = s.indexOf (':');
1079             if (p > -1) {
1080                 p = s.indexOf (':', p + 1);
1081                 if (p > -1) {
1082                     int q = s.indexOf (' ', p + 1);
1083                     if (q > -1)
1084                         i = s.mid (p + 1, q - p - 1).toInt ();
1085                 }
1086             }
1087         }
1088         sequence = eval_state->sequence;
1089     }
1090     return i;
1091 }
1092 
1093 int Last::toInt () const {
1094     if (eval_state->sequence != sequence) {
1095         sequence = eval_state->sequence;
1096         if (eval_state->iterator) {
1097             const NodeValue& v = eval_state->iterator->cur_value;
1098             if (v.node) {
1099                 if (v.attr) {
1100                     if (v.node->isElementNode())
1101                         i = static_cast<Element *> (v.node)->attributes().length();
1102                 } else if (v.node->parentNode()) {
1103                     i = 0;
1104                     for (Node* n = v.node->parentNode()->firstChild(); n; n = n->nextSibling())
1105                         ++i;
1106                 }
1107             }
1108         }
1109     }
1110     return i;
1111 }
1112 
1113 int Number::toInt () const {
1114     if (eval_state->sequence != sequence) {
1115         sequence = eval_state->sequence;
1116         if (first_child)
1117             i = first_child->toInt ();
1118     }
1119     return i;
1120 }
1121 
1122 int Position::toInt () const {
1123     if (eval_state->sequence != sequence) {
1124         sequence = eval_state->sequence;
1125         if (eval_state->iterator)
1126             i = eval_state->iterator->position + 1;
1127     }
1128     return i;
1129 }
1130 
1131 int StringLength::toInt () const {
1132     if (eval_state->sequence != sequence) {
1133         sequence = eval_state->sequence;
1134         if (first_child)
1135             i = first_child->toString ().length ();
1136         else if (eval_state->parent)
1137             i = eval_state->root.value ().length ();
1138         else
1139             i = 0;
1140     }
1141     return i;
1142 }
1143 
1144 QString Concat::toString () const {
1145     if (eval_state->sequence != sequence) {
1146         sequence = eval_state->sequence;
1147         string.clear ();
1148         for (AST *child = first_child; child; child = child->next_sibling)
1149             string += child->toString ();
1150     }
1151     return string;
1152 }
1153 
1154 QString EscapeUri::toString () const {
1155     if (eval_state->sequence != sequence) {
1156         sequence = eval_state->sequence;
1157         string.clear ();
1158         if (first_child)
1159             string = QUrl::toPercentEncoding (first_child->toString ());
1160     }
1161     return string;
1162 }
1163 
1164 QString StringJoin::toString () const {
1165     if (eval_state->sequence != sequence) {
1166         sequence = eval_state->sequence;
1167         string.clear ();
1168         AST *child = first_child;
1169         if (child) {
1170             ExprIterator* it = child->exprIterator(nullptr);
1171             if (!it->atEnd()) {
1172                 QString sep;
1173                 if (child->next_sibling)
1174                     sep = child->next_sibling->toString();
1175                 string = it->cur_value.value ();
1176                 it->next();
1177                 for (; !it->atEnd(); it->next())
1178                     string += sep + it->cur_value.value();
1179             }
1180             delete it;
1181         }
1182     }
1183     return string;
1184 }
1185 
1186 QString SubstringAfter::toString () const {
1187     if (eval_state->sequence != sequence) {
1188         sequence = eval_state->sequence;
1189         string.clear ();
1190         AST *child = first_child;
1191         if (child) {
1192             AST *next = child->next_sibling;
1193             if (next) {
1194                 QString s = child->toString ();
1195                 QString t = next->toString ();
1196                 int p = s.indexOf (t);
1197                 if (p > -1)
1198                     string = s.mid (p + t.length ());
1199             }
1200         }
1201     }
1202     return string;
1203 }
1204 
1205 QString SubstringBefore::toString () const {
1206     if (eval_state->sequence != sequence) {
1207         sequence = eval_state->sequence;
1208         string.clear ();
1209         AST *child = first_child;
1210         if (child) {
1211             AST *next = child->next_sibling;
1212             if (next) {
1213                 QString s = child->toString ();
1214                 QString t = next->toString ();
1215                 int p = s.indexOf (t);
1216                 if (p > -1)
1217                     string = s.left (p);
1218             }
1219         }
1220     }
1221     return string;
1222 }
1223 
1224 QString CurrentTime::toString () const {
1225     if (eval_state->sequence != sequence) {
1226         char buf[200];
1227         time_t t = time(nullptr);
1228         struct tm *lt = localtime(&t);
1229         if (lt && strftime (buf, sizeof (buf), "%H:%M:%S %z", lt))
1230             string = buf;
1231         sequence = eval_state->sequence;
1232     }
1233     return string;
1234 }
1235 
1236 QString CurrentDate::toString () const {
1237     if (eval_state->sequence != sequence) {
1238         char buf[200];
1239         time_t t = time(nullptr);
1240         struct tm *lt = localtime(&t);
1241         if (lt && strftime (buf, sizeof (buf), "%a, %d %b %Y %z", lt))
1242             string = buf;
1243         sequence = eval_state->sequence;
1244     }
1245     return string;
1246 }
1247 
1248 /*static void sortList (Sequence *lst, Expression *expr) {
1249     NodeValueItem *cur = lst->first ();
1250     Sequence lt;
1251     Sequence gt;
1252     expr->setRoot (cur->data.node);
1253     QString str = expr->toString ();
1254     for (NodeValueItem *itm = cur->nextSibling (); itm; ) {
1255         NodeValueItem *next = itm->nextSibling ();
1256         expr->setRoot (itm->data.node);
1257         int cmp = str.compare (expr->toString ());
1258         if (cmp < 0) {
1259             NodeValueItemPtr s = itm;
1260             lst->remove (itm);
1261             gt.append (itm);
1262         } else if (cmp > 0) {
1263             NodeValueItemPtr s = itm;
1264             lst->remove (itm);
1265             lt.append (itm);
1266         }
1267         itm = next;
1268     }
1269     if (lt.first ()) {
1270         sortList (&lt, expr);
1271         lst->splice (lst->first (), lt);
1272     }
1273     if (gt.first ()) {
1274         sortList (&gt, expr);
1275         lst->splice (NULL, gt);
1276     }
1277 }
1278 
1279 Sequence *Sort::toSequence () const {
1280     if (first_child) {
1281         Expression* exp = evaluateExpr(first_child->toString().toUtf8());
1282         if (exp) {
1283             exp->setRoot (eval_state->root.node);
1284             Sequence *lst = exp->toSequence ();
1285             if (lst->first () && first_child->next_sibling) {
1286                 Expression *sort_exp =
1287                     evaluateExpr(first_child->next_sibling->toString().toUtf8());
1288                 if (sort_exp) {
1289                     sortList (lst, sort_exp);
1290                     delete sort_exp;
1291                 }
1292             }
1293             delete exp;
1294             return lst;
1295         }
1296     }
1297     return AST::toSequence ();
1298 }
1299 */
1300 ExprIterator* SubSequence::exprIterator(ExprIterator* parent) const
1301 {
1302     struct SubSequenceIterator : public ExprIterator {
1303         int start;
1304         int length;
1305         SubSequenceIterator(ExprIterator* p, const AST* a)
1306             : ExprIterator(a ? a->exprIterator(p) : p), length(-1) {
1307             if (parent && a->next_sibling) {
1308                 a = a->next_sibling;
1309                 start = a->toInt();
1310                 if (start < 1)
1311                     start = 1;
1312                 if (a->next_sibling)
1313                     length = a->next_sibling->toInt();
1314                 for (; !parent->atEnd(); parent->next()) {
1315                     if (parent->position + 1 == start)
1316                         break;
1317                 }
1318                 if (!parent->atEnd())
1319                     cur_value = parent->cur_value;
1320             }
1321         }
1322         void next() override {
1323             assert(!parent->atEnd());
1324             parent->next();
1325             if (length < 0 || parent->position + 1 < start + length)
1326                 cur_value = parent->cur_value;
1327             else
1328                 cur_value = NodeValue(nullptr, nullptr);
1329             ++position;
1330         }
1331     };
1332     return new SubSequenceIterator(parent, first_child);
1333 }
1334 
1335 ExprIterator* Tokenize::exprIterator(ExprIterator* parent) const
1336 {
1337     struct TokenizeIterator : public ExprIterator {
1338         QString string;
1339         QRegExp reg_expr;
1340         int reg_pos;
1341         TokenizeIterator(ExprIterator* p, const AST* a) : ExprIterator(p), reg_pos(0) {
1342             if (a && a->next_sibling) {
1343                 string = a->toString();
1344                 reg_expr = QRegExp(a->next_sibling->toString());
1345                 pullNext();
1346             }
1347         }
1348         void pullNext() {
1349             if (reg_pos >= 0) {
1350                 reg_pos = reg_expr.indexIn(string, reg_pos);
1351                 if (reg_pos >= 0) {
1352                     int len = reg_expr.matchedLength();
1353                     cur_value = NodeValue(string.mid (reg_pos, len));
1354                     reg_pos += len;
1355                 }
1356             }
1357             if (reg_pos < 0)
1358                 cur_value = NodeValue(nullptr, nullptr);
1359         }
1360         void next() override {
1361             assert(!atEnd());
1362             pullNext();
1363             ++position;
1364         }
1365     };
1366     return new TokenizeIterator(parent, first_child);
1367 }
1368 
1369 #define BIN_OP_TO_INT(NAME,OP)                                           \
1370     AST *second_child = first_child->next_sibling;                       \
1371     AST::Type t1 = first_child->type(true);                              \
1372     AST::Type t2 = second_child->type(true);                             \
1373     if (AST::TInteger == t1 && AST::TInteger == t2)                      \
1374         return first_child->toInt() OP second_child->toInt();            \
1375     if (AST::TInteger == t1 && AST::TFloat == t2)                        \
1376         return (int) (first_child->toInt() OP                            \
1377                 second_child->toFloat());                                \
1378     if (AST::TFloat == t1 && AST::TInteger == t2)                        \
1379         return (int) (first_child->toFloat() OP                          \
1380                 second_child->toInt());                                  \
1381     if (AST::TFloat == t1 && AST::TFloat == t2)                          \
1382         return (int) (first_child->toFloat() OP                          \
1383                 second_child->toFloat());                                \
1384     return 0
1385 
1386 int Multiply::toInt () const {
1387     BIN_OP_TO_INT(multiply, *);
1388 }
1389 
1390 float Multiply::toFloat () const {
1391     return first_child->toFloat () * first_child->next_sibling->toFloat ();
1392 }
1393 
1394 static AST::Type binaryASTType (const AST *ast) {
1395     AST::Type t1 = ast->first_child->type(true);
1396     AST::Type t2 = ast->first_child->next_sibling->type(true);
1397     if (t1 == t2 && (AST::TInteger == t1 || AST::TFloat == t1))
1398         return t1;
1399     if ((AST::TInteger == t1 && AST::TFloat == t2) ||
1400             (AST::TInteger == t2 && AST::TFloat == t1))
1401         return AST::TFloat;
1402     return AST::TUnknown;
1403 }
1404 
1405 AST::Type Multiply::type(bool) const {
1406     return binaryASTType (this);
1407 }
1408 
1409 #ifdef KMPLAYER_EXPR_DEBUG
1410 void Multiply::dump () const {
1411     fprintf (stderr, "* [");
1412     AST::dump();
1413     fprintf (stderr, " ]");
1414 }
1415 #endif
1416 
1417 int Divide::toInt () const {
1418     BIN_OP_TO_INT(divide,/);
1419 }
1420 
1421 float Divide::toFloat () const {
1422     return first_child->toFloat () / first_child->next_sibling->toFloat ();
1423 }
1424 
1425 AST::Type Divide::type(bool) const {
1426     return binaryASTType (this);
1427 }
1428 
1429 #ifdef KMPLAYER_EXPR_DEBUG
1430 void Divide::dump () const {
1431     fprintf (stderr, "/ [");
1432     AST::dump();
1433     fprintf (stderr, " ]");
1434 }
1435 #endif
1436 
1437 int Modulus::toInt () const {
1438     AST::Type t1 = first_child->type(true);
1439     AST::Type t2 = first_child->next_sibling->type(true);
1440     if (t1 == t2 && (TInteger == t1 || TFloat == t1))
1441         return first_child->toInt () % first_child->next_sibling->toInt ();
1442     return 0;
1443 }
1444 
1445 float Modulus::toFloat () const {
1446     return toInt ();
1447 }
1448 
1449 AST::Type Modulus::type(bool) const {
1450     AST::Type t1 = first_child->type(true);
1451     AST::Type t2 = first_child->next_sibling->type(true);
1452     if (t1 == t2 && (TInteger == t1 || TFloat == t1))
1453         return TInteger;
1454     return TUnknown;
1455 }
1456 
1457 #ifdef KMPLAYER_EXPR_DEBUG
1458 void Modulus::dump () const {
1459     fprintf (stderr, "%% [");
1460     AST::dump();
1461     fprintf (stderr, " ]");
1462 }
1463 #endif
1464 
1465 int Plus::toInt ()  const{
1466     BIN_OP_TO_INT(plus,+);
1467 }
1468 
1469 float Plus::toFloat () const {
1470     return first_child->toFloat () + first_child->next_sibling->toFloat ();
1471 }
1472 
1473 AST::Type Plus::type(bool) const {
1474     return binaryASTType (this);
1475 }
1476 
1477 #ifdef KMPLAYER_EXPR_DEBUG
1478 void Plus::dump () const {
1479     fprintf (stderr, "+ [");
1480     AST::dump();
1481     fprintf (stderr, " ]");
1482 }
1483 #endif
1484 
1485 int Minus::toInt () const {
1486     return first_child->toInt() - first_child->next_sibling->toInt();
1487 }
1488 
1489 float Minus::toFloat () const {
1490     return first_child->toFloat () - first_child->next_sibling->toFloat ();
1491 }
1492 
1493 AST::Type Minus::type(bool) const {
1494     return binaryASTType (this);
1495 }
1496 
1497 #ifdef KMPLAYER_EXPR_DEBUG
1498 void Minus::dump () const {
1499     fprintf (stderr, "- [");
1500     AST::dump();
1501     fprintf (stderr, " ]");
1502 }
1503 #endif
1504 
1505 ExprIterator* Join::exprIterator(ExprIterator* parent) const {
1506     struct JoinIterator : public ExprIterator {
1507         const AST *ast;
1508         ExprIterator* it;
1509         JoinIterator(ExprIterator* p, const AST* a) : ExprIterator(p), ast(a), it(nullptr) {
1510             pullNext();
1511         }
1512         ~JoinIterator() override {
1513             delete it;
1514         }
1515         void pullNext() {
1516             if (it && it->atEnd()) {
1517                 delete it;
1518                 it = nullptr;
1519             }
1520             while (!it && ast) {
1521                 it = ast->exprIterator(nullptr);
1522                 ast = ast->next_sibling;
1523                 if (it->atEnd()) {
1524                     delete it;
1525                     it = nullptr;
1526                 }
1527             }
1528             if (it)
1529                 cur_value = it->cur_value;
1530             else
1531                 cur_value = NodeValue(nullptr, nullptr);
1532         }
1533         void next() override {
1534             assert(!atEnd());
1535             it->next();
1536             pullNext();
1537             ++position;
1538         }
1539     };
1540     return new JoinIterator(parent, first_child);
1541 }
1542 
1543 #ifdef KMPLAYER_EXPR_DEBUG
1544 void Join::dump () const {
1545     fprintf (stderr, "| [");
1546     AST::dump();
1547     fprintf (stderr, " ]");
1548 }
1549 #endif
1550 
1551 bool Comparison::toBool () const {
1552     AST::Type t1 = first_child->type(true);
1553     AST::Type t2 = first_child->next_sibling->type(true);
1554     switch (comp_type) {
1555     case lt:
1556         return first_child->toFloat () < first_child->next_sibling->toFloat ();
1557     case lteq:
1558         return first_child->toInt () <= first_child->next_sibling->toInt ();
1559     case gt:
1560         return first_child->toFloat () > first_child->next_sibling->toFloat ();
1561     case gteq:
1562         return first_child->toInt () >= first_child->next_sibling->toInt ();
1563     case eq:
1564         if (t1 == AST::TString || t2 == AST::TString) {
1565             return first_child->toString () ==
1566                 first_child->next_sibling->toString ();
1567         }
1568         return first_child->toInt () == first_child->next_sibling->toInt ();
1569     case noteq:
1570         return first_child->toInt () != first_child->next_sibling->toInt ();
1571     case land:
1572         return first_child->toBool () && first_child->next_sibling->toBool ();
1573     case lor:
1574         return first_child->toBool () || first_child->next_sibling->toBool ();
1575     }
1576     return false;
1577 }
1578 
1579 #ifdef KMPLAYER_EXPR_DEBUG
1580 void Comparison::dump () const {
1581     switch (comp_type) {
1582     case lt:
1583         fprintf (stderr, "< [");
1584         break;
1585     case lteq:
1586         fprintf (stderr, "<= [");
1587         break;
1588     case gt:
1589         fprintf (stderr, "> [");
1590         break;
1591     case gteq:
1592         fprintf (stderr, ">= [");
1593         break;
1594     case eq:
1595         fprintf (stderr, "== [");
1596         break;
1597     case noteq:
1598         fprintf (stderr, "!= [");
1599         break;
1600     case land:
1601         fprintf (stderr, "&& [");
1602         break;
1603     case lor:
1604         fprintf (stderr, "|| [");
1605     }
1606     AST::dump();
1607     fprintf (stderr, " ]");
1608 }
1609 #endif
1610 
1611 
1612 struct Parser {
1613     enum { TEof=-1, TDouble=-2, TLong=-3, TIdentifier=-4, TWhiteSpace=-5 };
1614 
1615     const char *source;
1616     const char *cur;
1617 
1618     int cur_token;
1619     long long_value;
1620     double double_value;
1621     QString str_value;
1622     QString error;
1623 
1624     Parser(const char* s) : source(s), cur(source) {}
1625     void nextToken(bool skip_whitespace=true);
1626     void setError(const char* err) {
1627         fprintf(stderr, "Error at %td: %s\n", cur-source, err);
1628     }
1629 };
1630 
1631 void Parser::nextToken(bool skip_whitespace) {
1632     const char* begin = cur;
1633     bool is_num = false;
1634     bool is_fractal = false;
1635     while (true) {
1636         char c = *cur;
1637         switch (c) {
1638         case 0:
1639             if (begin == cur) {
1640                 cur_token = TEof;
1641                 return;
1642             }
1643             goto interp;
1644         case ' ':
1645         case '\t':
1646         case '\n':
1647         case '\r':
1648             if (begin == cur) {
1649                 if (!skip_whitespace) {
1650                     cur_token = TWhiteSpace;
1651                     ++cur;
1652                     return;
1653                 }
1654                 ++begin;
1655                 break;
1656             }
1657             goto interp;
1658         case '.':
1659             if (is_num && !is_fractal) {
1660                 is_fractal = true;
1661                 break;
1662             }
1663             // fall through
1664         default:
1665             if ((is_num || begin == cur) && c >= '0' && c <= '9') {
1666                 is_num = true;
1667                 break;
1668             }
1669             if (is_num && !(c >= '0' && c <= '9'))
1670                 goto interp;
1671             if (!((c >= 'a' && c <= 'z')
1672                         || (c >= 'A' && c <= 'Z')
1673                         || (cur != begin && c >= '0' && c <= '9')
1674                         || c == '_'
1675                         || (cur != begin && c == '-')
1676                         || (unsigned char)c > 127)) {
1677                 if (begin == cur) {
1678                     cur_token = c;
1679                     ++cur;
1680                     return;
1681                 }
1682                 goto interp;
1683             }
1684         }
1685         cur++;
1686     }
1687 interp:
1688     if (is_num && cur - begin < 63) {
1689         char buf[64];
1690         memcpy(buf, begin, cur - begin);
1691         buf[cur - begin] = 0;
1692         if (is_fractal) {
1693             cur_token = TDouble;
1694             double_value = strtod(buf, nullptr);
1695         } else {
1696             cur_token = TLong;
1697             long_value = strtol(buf, nullptr, 10);
1698         }
1699     } else {
1700         cur_token = TIdentifier;
1701         str_value = QString::fromUtf8(QByteArray(begin, cur-begin));
1702     }
1703 }
1704 
1705 static bool parseStatement (Parser *parser, AST *ast);
1706 
1707 
1708 static bool parsePredicates (Parser *parser, AST *ast) {
1709     AST pred (new EvalState (ast->eval_state));
1710     while (true) {
1711         if (parseStatement (parser, &pred)) {
1712             if (']' != parser->cur_token)
1713                 return false;
1714             if (pred.first_child) {
1715                 AST* child = releaseASTChildren(&pred);
1716                 assert(!child->next_sibling);
1717                 switch (child->type(false)) {
1718                     case AST::TBool:
1719                         break;
1720                     case AST::TInteger:
1721                     case AST::TFloat:
1722                         child->next_sibling = new Position(pred.eval_state);
1723                         child = new Comparison(pred.eval_state, Comparison::eq, child);
1724                         break;
1725                     default: {
1726                         AST* bfunc = new Boolean(pred.eval_state);
1727                         bfunc->first_child = child;
1728                         child = bfunc;
1729                         break;
1730                     }
1731                 }
1732                 appendASTChild(ast, child);
1733             }
1734         } else if (']' != parser->cur_token) {
1735             return false;
1736         }
1737         parser->nextToken();
1738         if ('[' != parser->cur_token)
1739             break;
1740         parser->nextToken();
1741     }
1742     return true;
1743 }
1744 
1745 static bool parseStep (Parser *parser, AST *ast) {
1746 #ifdef KMPLAYER_EXPR_DEBUG
1747     fprintf (stderr, "%s enter str:'%s'\n", __FUNCTION__, parser->cur);
1748 #endif
1749     AST *entry = nullptr;
1750     int axes = Step::ChildAxis;
1751     if ('/' == parser->cur_token) {
1752         axes = Step::DescendantAxis;
1753         parser->nextToken();
1754     }
1755     QString ns_identifier;
1756     QString identifier;
1757     Step::NodeType node_type = Step::ElementType;
1758     int prev_token = Parser::TEof;
1759     while (true ) {
1760         switch (parser->cur_token) {
1761         case '@':
1762             axes &= ~Step::ChildAxis;
1763             axes |= Step::AttributeAxis;
1764             break;
1765         case '.':
1766             if ( axes & Step::SelfAxis) {
1767                 axes &= ~Step::SelfAxis;
1768                 axes |= Step::ParentAxis;
1769             } else {
1770                 axes &= ~Step::ChildAxis;
1771                 axes |= Step::SelfAxis;
1772             }
1773             node_type = Step::AnyType;
1774             break;
1775         case '*':
1776             //identifier = "*";
1777             break;
1778         case ':':
1779             if (prev_token == ':') {
1780                 axes &= ~(Step::ChildAxis | Step::NamespaceAxis);
1781                 if (ns_identifier.startsWith("ancestor")) {
1782                     axes |= Step::AncestorAxis;
1783                     if (ns_identifier.endsWith("self"))
1784                         axes |= Step::SelfAxis;
1785                 } else if (ns_identifier == "attribute") {
1786                     axes |= Step::AttributeAxis;
1787                 } else if (ns_identifier == "child") {
1788                     axes |= Step::ChildAxis;
1789                 } else if (ns_identifier.startsWith("descendant")) {
1790                     axes |= Step::DescendantAxis;
1791                     if (ns_identifier.endsWith("self"))
1792                         axes |= Step::SelfAxis;
1793                 } else if (ns_identifier == "following") {
1794                     axes |= Step::FollowingAxis;
1795                 } else if (ns_identifier == "following-sibling") {
1796                     axes |= Step::FollowingSiblingAxis;
1797                 } else if (ns_identifier == "namespace") {
1798                     axes |= Step::NamespaceAxis;
1799                 } else if (ns_identifier == "parent") {
1800                     axes |= Step::ParentAxis;
1801                 } else if (ns_identifier == "preceding") {
1802                     axes |= Step::PrecedingAxis;
1803                 } else if (ns_identifier == "preceding-sibling") {
1804                     axes |= Step::PrecedingSiblingAxis;
1805                 } else if (ns_identifier == "self") {
1806                     axes |= Step::SelfAxis;
1807                 }
1808                 ns_identifier.clear();
1809             } else {
1810                 axes |= Step::NamespaceAxis;
1811                 ns_identifier = identifier;
1812                 identifier.clear();
1813             }
1814             break;
1815         case Parser::TIdentifier:
1816             identifier = parser->str_value;
1817             break;
1818         default:
1819             goto location_done;
1820         }
1821         prev_token = parser->cur_token;
1822         parser->nextToken(false);
1823     }
1824 location_done:
1825     if (Parser::TWhiteSpace == parser->cur_token)
1826         parser->nextToken();
1827     if (!ns_identifier.isEmpty() && !(axes & Step::SelfAxis) && identifier != "*")  // FIXME namespace support
1828         identifier = ns_identifier + ':' + identifier;
1829     if ('(' == parser->cur_token) {
1830         parser->nextToken();
1831         if (')' != parser->cur_token) {
1832             parser->setError("Expected )");
1833             return false;
1834         }
1835         parser->nextToken();
1836         if (identifier == "text") {
1837             node_type = Step::TextType;
1838         } else if (identifier == "node") {
1839             node_type = Step::AnyType;
1840         } else {
1841             parser->setError("Expected 'text' or 'node'");
1842             return false;
1843         }
1844         identifier.clear();
1845     }
1846     entry = new Step(ast->eval_state, identifier, axes, node_type);
1847     AST fast (ast->eval_state);
1848     if ('[' == parser->cur_token) {
1849         parser->nextToken();
1850         if (!parsePredicates (parser, &fast))
1851             return false;
1852         entry->next_sibling = releaseASTChildren (&fast);
1853         entry = new PredicateFilter (ast->eval_state, entry);
1854     }
1855     appendASTChild (ast, entry);
1856 #ifdef KMPLAYER_EXPR_DEBUG
1857     fprintf (stderr, "%s success end:'%s'\n", __FUNCTION__, parser->cur);
1858 #endif
1859     return true;
1860 }
1861 
1862 static bool parsePath (Parser *parser, AST *ast) {
1863 #ifdef KMPLAYER_EXPR_DEBUG
1864     fprintf (stderr, "%s enter str:'%s'\n", __FUNCTION__, parser->cur);
1865 #endif
1866     Path path (ast->eval_state, nullptr, false);
1867     bool has_any = false;
1868 
1869     bool start_contextual =  '/' != parser->cur_token;
1870     if ('/' == parser->cur_token) {
1871         parser->nextToken();
1872     } else if (!ast->eval_state->parent
1873             && !ast->eval_state->def_root_tag.isEmpty ()) {
1874         appendASTChild (&path, new Step (ast->eval_state,
1875                     ast->eval_state->def_root_tag, Step::ChildAxis, Step::ElementType));
1876     }
1877     if (parseStep (parser, &path)) {
1878         has_any = true;
1879         while ('/' == parser->cur_token) {
1880             parser->nextToken();
1881             if (!parseStep (parser, &path))
1882                 break;
1883         }
1884     }
1885     if (has_any) {
1886         appendASTChild (ast, new Path (ast->eval_state, releaseASTChildren (&path), start_contextual));
1887 #ifdef KMPLAYER_EXPR_DEBUG
1888         fprintf (stderr, "%s success end:'%s'\n", __FUNCTION__, parser->cur);
1889 #endif
1890         return true;
1891     }
1892     return false;
1893 }
1894 
1895 static bool parseFunction (Parser *parser, const QString &name, AST *ast) {
1896 #ifdef KMPLAYER_EXPR_DEBUG
1897     fprintf (stderr, "%s enter str:'%s'\n", __FUNCTION__, parser->cur);
1898 #endif
1899     AST fast (ast->eval_state);
1900     while (Parser::TEof != parser->cur_token) {
1901         switch (parser->cur_token) {
1902         case ')': {
1903             parser->nextToken();
1904             AST *func = nullptr;
1905             if (name == "boolean")
1906                 func = new Boolean(ast->eval_state);
1907             else if (name == "concat")
1908                 func = new Concat (ast->eval_state);
1909             else if (name == "contains")
1910                 func = new Contains (ast->eval_state);
1911             else if (name == "count")
1912                 func = new Count (ast->eval_state);
1913             else if (name == "hours-from-time")
1914                 func = new HoursFromTime (ast->eval_state);
1915             else if (name == "minutes-from-time")
1916                 func = new MinutesFromTime (ast->eval_state);
1917             else if (name == "seconds-from-time")
1918                 func = new SecondsFromTime (ast->eval_state);
1919             else if (name == "current-time")
1920                 func = new CurrentTime (ast->eval_state);
1921             else if (name == "current-date")
1922                 func = new CurrentDate (ast->eval_state);
1923             else if (name == "last")
1924                 func = new Last (ast->eval_state);
1925             else if (name == "not")
1926                 func = new Not (ast->eval_state);
1927             else if (name == "number")
1928                 func = new Number (ast->eval_state);
1929             else if (name == "position")
1930                 func = new Position (ast->eval_state);
1931             //else if (name == "sort")
1932                 //func = new Sort (ast->eval_state);
1933             else if (name == "starts-with")
1934                 func = new StartsWith (ast->eval_state);
1935             else if (name == "string-join")
1936                 func = new StringJoin (ast->eval_state);
1937             else if (name == "string-length")
1938                 func = new StringLength (ast->eval_state);
1939             else if (name == "subsequence")
1940                 func = new SubSequence (ast->eval_state);
1941             else if (name == "substring-after")
1942                 func = new SubstringAfter (ast->eval_state);
1943             else if (name == "substring-before")
1944                 func = new SubstringBefore (ast->eval_state);
1945             else if (name == "tokenize")
1946                 func = new Tokenize (ast->eval_state);
1947             else if (name == "escape-uri")
1948                 func = new EscapeUri (ast->eval_state);
1949             else
1950                 return false;
1951             appendASTChild (ast, func);
1952             func->first_child = releaseASTChildren (&fast);
1953 #ifdef KMPLAYER_EXPR_DEBUG
1954             fprintf (stderr, "%s succes str:'%s'\n", __FUNCTION__, parser->cur);
1955 #endif
1956             return true;
1957         }
1958         case ',':
1959             parser->nextToken();
1960             break;
1961         default:
1962             if (!parseStatement (parser, &fast))
1963                 return false;
1964         }
1965     }
1966     return false;
1967 }
1968 
1969 static bool parseFactor (Parser *parser, AST *ast) {
1970 #ifdef KMPLAYER_EXPR_DEBUG
1971     fprintf (stderr, "%s enter str:'%s'\n", __FUNCTION__, parser->cur);
1972 #endif
1973     AST fast (ast->eval_state);
1974     int sign = 1;
1975     if ('+' == parser->cur_token || '-' == parser->cur_token) {
1976         sign = '-' == parser->cur_token ? -1 : 1;
1977         parser->nextToken();
1978     }
1979     switch (parser->cur_token) {
1980     case Parser::TEof:
1981         return true;
1982     case '(':
1983         parser->nextToken();
1984         if (!parseStatement (parser, &fast))
1985             return false;
1986         if (')' != parser->cur_token)
1987             return false;
1988         parser->nextToken();
1989         break;
1990     case '.':
1991     case '@':
1992     case '*':
1993     case '/':
1994         if (!parsePath (parser, &fast))
1995             return false;
1996         break;
1997     case '\'':
1998     case '"': {
1999         const char* s = parser->cur;
2000         while (*s && *s != parser->cur_token)
2001             ++s;
2002         if (!*s) {
2003             parser->setError("expected string literal");
2004             parser->cur = s;
2005             parser->cur_token = Parser::TEof;
2006             return false;
2007         }
2008         appendASTChild(&fast, new StringLiteral(ast->eval_state, QString::fromUtf8(QByteArray(parser->cur, s - parser->cur))));
2009         parser->cur = ++s;
2010         parser->nextToken();
2011 #ifdef KMPLAYER_EXPR_DEBUG
2012         fprintf (stderr, "%s success end:'%s' cur token %c\n", __FUNCTION__, parser->cur, parser->cur_token);
2013 #endif
2014         break;
2015     }
2016     case Parser::TDouble:
2017         appendASTChild (&fast, new Float (ast->eval_state, (float)(sign * parser->double_value)));
2018         parser->nextToken();
2019         break;
2020     case Parser::TLong:
2021         appendASTChild (&fast,  new Integer (ast->eval_state, (int)(sign * parser->long_value)));
2022         parser->nextToken();
2023         break;
2024     case Parser::TIdentifier: {
2025         QString str = parser->str_value;
2026         const char* cur = parser->cur;
2027         parser->nextToken();
2028         if ('(' == parser->cur_token) {
2029             parser->nextToken();
2030             if (!parseFunction (parser, str, &fast))
2031                 return false;
2032         } else {
2033             parser->cur = cur;
2034             parser->cur_token = Parser::TIdentifier;
2035             parser->str_value = str;
2036             if (!parsePath (parser, &fast))
2037                 return false;
2038         }
2039         break;
2040     }
2041     default:
2042         return false;
2043     }
2044     if ('[' == parser->cur_token) {
2045         parser->nextToken();
2046         if (!parsePredicates (parser, &fast))
2047             return false;
2048         appendASTChild (ast,
2049                 new PredicateFilter (ast->eval_state, releaseASTChildren (&fast)));
2050     } else {
2051         appendASTChild (ast, releaseASTChildren (&fast));
2052     }
2053     return true;
2054 }
2055 
2056 static bool parseTerm (Parser *parser, AST *ast) {
2057 #ifdef KMPLAYER_EXPR_DEBUG
2058     fprintf (stderr, "%s enter str:'%s'\n", __FUNCTION__, parser->cur);
2059 #endif
2060     if (parseFactor (parser, ast)) {
2061         while (true) {
2062             int op = 0;
2063             if ('*' == parser->cur_token) {
2064                 op = '*';
2065             } else if (Parser::TIdentifier == parser->cur_token) {
2066                 if ( parser->str_value == "div")
2067                     op = '/';
2068                 else if ( parser->str_value == "mod")
2069                     op = '%';
2070             }
2071             if (!op)
2072                 break;
2073             parser->nextToken();
2074             AST tmp (ast->eval_state);
2075             if (parseFactor (parser, &tmp)) {
2076                 AST *chlds = releaseLastASTChild (ast);
2077                 chlds->next_sibling = releaseASTChildren (&tmp);
2078                 appendASTChild (ast,
2079                         op == '*'
2080                         ? (AST *) new Multiply (ast->eval_state, chlds)
2081                         : op == '/'
2082                         ? (AST *) new Divide (ast->eval_state, chlds)
2083                         : (AST *) new Modulus (ast->eval_state, chlds));
2084             } else {
2085                 parser->setError("expected factor");
2086                 return false;
2087             }
2088         }
2089 #ifdef KMPLAYER_EXPR_DEBUG
2090         fprintf (stderr, "%s success end:'%s'\n", __FUNCTION__, parser->cur);
2091 #endif
2092         return true;
2093     }
2094     return false;
2095 }
2096 
2097 static bool parseExpression (Parser *parser, AST *ast) {
2098 #ifdef KMPLAYER_EXPR_DEBUG
2099     fprintf (stderr, "%s enter str:'%s'\n", __FUNCTION__, parser->cur);
2100 #endif
2101     if (parseTerm (parser, ast)) {
2102         while (true) {
2103             int op = parser->cur_token;
2104             if (op != '+' && op != '-' && op != '|')
2105                 break;
2106             parser->nextToken();
2107             AST tmp (ast->eval_state);
2108             if (parseTerm (parser, &tmp)) {
2109                 AST *chlds = releaseLastASTChild (ast);
2110                 chlds->next_sibling = releaseASTChildren (&tmp);
2111                 appendASTChild (ast, op == '+'
2112                         ? (AST *) new Plus (ast->eval_state, chlds)
2113                         :  op == '-'
2114                         ? (AST *) new Minus (ast->eval_state, chlds)
2115                         : (AST *) new Join (ast->eval_state, chlds));
2116             } else {
2117                 parser->setError("expected term");
2118                 return false;
2119             }
2120         }
2121 #ifdef KMPLAYER_EXPR_DEBUG
2122         fprintf (stderr, "%s success end:'%s'\n", __FUNCTION__, parser->cur);
2123 #endif
2124         return true;
2125     }
2126     return false;
2127 }
2128 
2129 static bool parseStatement (Parser *parser, AST *ast) {
2130 #ifdef KMPLAYER_EXPR_DEBUG
2131     fprintf (stderr, "%s enter str:'%s'\n", __FUNCTION__, parser->cur);
2132 #endif
2133     if (parseExpression (parser, ast)) {
2134         bool skip_next_token = false;
2135         enum EComparison {
2136             err=-1, asign,
2137             lt=Comparison::lt, lteq, eq, noteq, gt, gteq, land, lor
2138         } comparison = err;
2139         switch (parser->cur_token) {
2140         case '<':
2141             parser->nextToken();
2142             if (parser->cur_token == '=') {
2143                 comparison = lteq;
2144             } else {
2145                 skip_next_token = true;
2146                 comparison = lt;
2147             }
2148             break;
2149         case '>':
2150             parser->nextToken();
2151             if ('=' == parser->cur_token) {
2152                 comparison = gteq;
2153             } else {
2154                 skip_next_token = true;
2155                 comparison = gt;
2156             }
2157             break;
2158         case '=':
2159             comparison = eq;
2160             break;
2161         case '!':
2162             parser->nextToken();
2163             if ('=' == parser->cur_token) {
2164                 parser->setError("expected =");
2165                 return false;
2166             }
2167             comparison = noteq;
2168             break;
2169         case Parser::TIdentifier:
2170             if (parser->str_value == "and")
2171                 comparison = land;
2172             else if (parser->str_value == "or")
2173                 comparison = lor;
2174             break;
2175         default:
2176             return true;
2177         }
2178         AST tmp (ast->eval_state);
2179         if (!skip_next_token)
2180             parser->nextToken();
2181         if (parseExpression (parser, &tmp)) {
2182             AST *chlds = releaseLastASTChild (ast);
2183             chlds->next_sibling = releaseASTChildren (&tmp);
2184             appendASTChild (ast, new Comparison (ast->eval_state,
2185                         (Comparison::CompType)comparison, chlds));
2186         } else {
2187             parser->setError("expected epression");
2188             return false;
2189         }
2190 
2191 #ifdef KMPLAYER_EXPR_DEBUG
2192         fprintf (stderr, "%s success end:'%s'\n", __FUNCTION__, parser->cur);
2193 #endif
2194         return true;
2195     }
2196     return false;
2197 }
2198 
2199 Expression* KMPlayer::evaluateExpr(const QByteArray& expr, const QString &root) {
2200     EvalState *eval_state = new EvalState (nullptr, root);
2201     AST ast (eval_state);
2202     Parser parser(expr.constData());
2203     parser.nextToken ();
2204     if (parseStatement (&parser, &ast)) {
2205 #ifdef KMPLAYER_EXPR_DEBUG
2206         ast.dump();
2207         fprintf (stderr, "\n");
2208 #endif
2209         return releaseASTChildren (&ast);
2210     }
2211     return nullptr;
2212 }
2213 /*
2214 int main (int argc, char **argv) {
2215     AST ast;
2216     const char *end;
2217     if (argc < 2) {
2218         fprintf (stderr, "Usage %s <expr>\n", argv[0]);
2219         return 1;
2220     }
2221     printf ("expr '%s' parsed:%d\n", argv[1], parseStatement (argv[1], &end, &ast));
2222     ast.dump();
2223     if (ast.first_child)
2224         printf ("\ni:%d f:%.4f b:%d s:%s\n",
2225                 ast.first_child->toInt(), ast.first_child->toFloat(), ast.first_child->toBool(), ast.first_child->toString());
2226     return 0;
2227 }*/