File indexing completed on 2024-03-24 04:56:52
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 (<, expr); 1271 lst->splice (lst->first (), lt); 1272 } 1273 if (gt.first ()) { 1274 sortList (>, 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 }*/