From e9ae80694875f869892f13f4fcaf1170a00dea41 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdewebdev@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kommander/widget/expression.cpp | 332 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 kommander/widget/expression.cpp (limited to 'kommander/widget/expression.cpp') diff --git a/kommander/widget/expression.cpp b/kommander/widget/expression.cpp new file mode 100644 index 00000000..88d46b51 --- /dev/null +++ b/kommander/widget/expression.cpp @@ -0,0 +1,332 @@ +/*************************************************************************** + expression.cpp - Expression parser + ------------------- + copyright : (C) 2004 Michal Rudolf + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "expression.h" + +#include + +Expression::Expression() : m_start(0), m_error(false) +{ +} + +Expression::Expression(const QString& expr) +{ + *this = expr; +} + +Expression& Expression::operator=(const QString& s) +{ + m_start = 0; + m_error = false; + m_parts.clear(); + const QString single = "()<>!+-/*%"; + int start = 0; + int len = s.length(); + int i = 0; + while (i < len) + { + if (((s[i] == '>' || s[i] == '<' || s[i] == '=' || s[i] == '!') && + s[i + 1] == '=') || (s[i] == '<' && s[i + 1] == '>')) + { + m_parts.append(QVariant(s.mid(i, 2))); + i += 2; + } else if (s[i].isDigit()) + { + i++; + bool decimal = false; + while (i < len && (s[i].isDigit() || (!decimal && s[i] == QChar('.')))) + { + if (s[i] == '.') + decimal = true; + i++; + } + if (decimal) + m_parts.append(QVariant(s.mid(start, i - start).toDouble())); + else + m_parts.append(QVariant(s.mid(start, i - start).toInt())); + } else if (single.contains(s[i])) + m_parts.append(QVariant(QString(s[i++]))); + else if (s[i] == '\"') + { + i++; + while (i < len && s[i] != '\"') + i++; + m_parts.append(QVariant(s.mid(start + 1, i - start - 1))); + i++; + } else if (s[i].isSpace()) + while (i < len && s[i].isSpace()) + i++; + else + { + while (i < len && !s[i].isSpace()) + i++; + QString keyword = s.mid(start, i - start); + if (keyword == "true") + m_parts.append(QVariant(true)); + else if (keyword == "false") + m_parts.append(QVariant(false)); + else /* will be deprecated soon */ + m_parts.append(QVariant(keyword)); + } + start = i; + } + return *this; +} + +QString Expression::next() const +{ + if (m_start < m_parts.count()) + return m_parts[m_start].toString(); + else + return QString(); +} + +bool Expression::validate() +{ + if (m_start >= m_parts.count()) + setError(); + return !m_error; +} +Expression::Type Expression::commonType(const QVariant v1, const QVariant v2) const +{ + if (v1.type() == QVariant::String || v2.type() == QVariant::String) + return TypeString; + else if (v1.type() == QVariant::Double || v2.type() == QVariant::Double) + return TypeDouble; + return TypeInt; +} + +static int expression_compareDouble(const double A, const double B) +{ + return A=" || cmp == ">" || cmp == "<>" || cmp == "!=") + { + m_start++; + QVariant value2 = parseAdd(); + if (cmp == "<") + return compare(value, value2) < 0; + else if (cmp == "<=") + return compare(value, value2) <= 0; + else if (cmp == "==") + return compare(value, value2) == 0; + else if (cmp == ">=") + return compare(value, value2) >= 0; + else if (cmp == "<>" || cmp == "!=") + return compare(value, value2) != 0; + else + return compare(value, value2) > 0; + } + return value; +} + +QVariant Expression::parseNot() +{ + if (next() == "!" || next() == "not") + { + m_start++; + return !parseComparison().asBool(); + } + else + return parseComparison(); +} + +QVariant Expression::parseAnd() +{ + if (!validate()) return -1; + QVariant value = parseNot(); + while (next() == "&&" || next() == "and") + { + m_start++; + value = parseNot().toBool() && value.toBool(); + } + + return value; +} + +QVariant Expression::parseOr() +{ + if (!validate()) return -1; + QVariant value = parseAnd(); + while (next() == "||" || next() == "or") + { + m_start++; + value = parseAnd().toBool() || value.toBool(); + } + return value; +} + +QVariant Expression::parse() +{ + return parseOr(); +} + +QVariant Expression::value(bool* valid) +{ + m_start = 0; + m_error = false; + QVariant val = parse(); + if (valid) + *valid = !m_error && m_start == m_parts.count(); + return val; +} + +QVariant Expression::value(const QString& s, bool* valid) +{ + *this = s; + return value(valid); +} + +bool Expression::isTrue(const QString& s, bool* valid) +{ + QVariant v = value(s, valid); + return (v.type() == QVariant::String && !v.toString().isNull()) || + (v.type() != QVariant::String && v.toInt() != 0); +} + -- cgit v1.2.3