From: hama Date: Tue, 15 Sep 2015 21:52:48 +0000 (+0200) Subject: ReListMatcher + ReIncludeExcludeMatcher X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=e0a2c01bedc536439c62087518d9b6cfce372130;p=reqt ReListMatcher + ReIncludeExcludeMatcher --- diff --git a/base/ReQStringUtils.cpp b/base/ReQStringUtils.cpp index 65dabff..a31bc72 100644 --- a/base/ReQStringUtils.cpp +++ b/base/ReQStringUtils.cpp @@ -106,7 +106,7 @@ ReString ReQStringUtils::extensionOf(const ReString& filename) { * otherwise: the length of the integer */ int ReQStringUtils::lengthOfUInt64(const ReString& text, int start, int radix, - quint64* pValue) { + quint64* pValue) { int inputLength = text.size(); int64_t value = 0; int ix = start; @@ -141,7 +141,7 @@ int ReQStringUtils::lengthOfUInt64(const ReString& text, int start, int radix, } } else { throw ReException("ReQStringUtil::lengthOfInt(): wrong radix: %d", - radix); + radix); } if (pValue != NULL) *pValue = value; @@ -159,7 +159,7 @@ int ReQStringUtils::lengthOfUInt64(const ReString& text, int start, int radix, * otherwise: the length of the integer */ int ReQStringUtils::lengthOfUInt(const ReString& text, int start, int radix, - uint* pValue) { + uint* pValue) { quint64 value; int rc = lengthOfUInt64(text, start, radix, &value); if (pValue != NULL) @@ -180,7 +180,7 @@ int ReQStringUtils::lengthOfUInt(const ReString& text, int start, int radix, * otherwise: the length of the date in the string */ int ReQStringUtils::lengthOfDate(const ReString& text, int start, - QDate* value) { + QDate* value) { uint day = 0; uint month = 0; uint year = 0; @@ -228,7 +228,7 @@ int ReQStringUtils::lengthOfDate(const ReString& text, int start, } } if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1970 - || year > 2100) + || year > 2100) length = 0; if (length != 0 && value != NULL) *value = QDate(year, month, day); @@ -250,7 +250,7 @@ int ReQStringUtils::lengthOfDate(const ReString& text, int start, * otherwise: the length of the date in the string */ int ReQStringUtils::lengthOfDateTime(const ReString& text, int start, - bool allowDateOnly, bool allowTimeOnly, QDateTime* value) { + bool allowDateOnly, bool allowTimeOnly, QDateTime* value) { QDate date; QTime time; int length = lengthOfDate(text, start, &date); @@ -292,7 +292,7 @@ int ReQStringUtils::lengthOfDateTime(const ReString& text, int start, * otherwise: the length of the date in the string */ int ReQStringUtils::lengthOfTime(const ReString& text, int start, - QTime* value) { + QTime* value) { uint hour = 0; uint minute = 0; uint sec = 0; @@ -336,7 +336,7 @@ int ReQStringUtils::lengthOfTime(const ReString& text, int start, * otherwise: the length of the floating point number */ int ReQStringUtils::lengthOfReal(const ReString& text, int start, - qreal* pValue) { + qreal* pValue) { int inputLength = text.size(); qreal value = 0.0; int cc; @@ -450,7 +450,7 @@ QString ReQStringUtils::pathAppend(const QString& base, const QString& path) { */ QString ReQStringUtils::replaceExtension(const QString& path, - const QString& ext) { + const QString& ext) { QString oldExt = extensionOf(path); QString rc; if (oldExt.isEmpty()) @@ -471,7 +471,7 @@ QString ReQStringUtils::replaceExtension(const QString& path, * false: unknown name found (not replaced) */ bool ReQStringUtils::replacePlaceholders(QString& text, - const QMap& placeholders, QString* error) { + const QMap& placeholders, QString* error) { int start = 0; bool rc = true; QString name; @@ -510,7 +510,7 @@ bool ReQStringUtils::replacePlaceholders(QString& text, * otherwise: the length is incremented */ void ReQStringUtils::skipExpected(const ReString& text, QChar expected, - int& index, int& length) { + int& index, int& length) { if (length == 0) { // error state, do nothing } else if (index >= text.length() || text[index] != expected) { @@ -533,7 +533,7 @@ void ReQStringUtils::skipExpected(const ReString& text, QChar expected, * @return buffer */ char*ReQStringUtils::utf8(const ReString& source, char buffer[], - size_t bufferSize) { + size_t bufferSize) { QByteArray val = source.toUtf8(); if (val.length() < (int) bufferSize) bufferSize = val.length() + 1; @@ -545,8 +545,8 @@ char*ReQStringUtils::utf8(const ReString& source, char buffer[], class ReParserException: public ReException { public: ReParserException(const QString& message) : - ReException(), - m_message(message) { + ReException(), + m_message(message) { } public: QString m_message; @@ -559,11 +559,11 @@ public: * example: "kibyte:1024;kbyte:1000;mibyte:1048576;mbyte:1000000" */ ReUnitParser::ReUnitParser(const QString& expr, const char* unitList, - bool parseAtOnce) : - m_result(0), - m_expr(expr), - m_message(), - m_unitList(unitList) { + bool parseAtOnce) : + m_result(0), + m_expr(expr), + m_message(), + m_unitList(unitList) { normalize(); if (parseAtOnce) parse(); @@ -632,7 +632,7 @@ void ReUnitParser::normalize() { // This makes the syntax easier to parse: only one sum operator ('+'). for (int ii = m_expr.length() - 1; ii > 0; ii--) { if (m_expr[ii] == '-' && m_expr[ii - 1] != '+' - && m_expr[ii - 1] != '*') { + && m_expr[ii - 1] != '*') { m_expr.insert(ii, '+'); } } @@ -654,8 +654,8 @@ void ReUnitParser::parse() { QStringList powerOperands = it2->split("^"); if (powerOperands.count() > 2) throw ReParserException( - QObject::tr( - "more than 2 power operators, e.g. '2^3^4'")); + QObject::tr( + "more than 2 power operators, e.g. '2^3^4'")); QStringList::const_iterator it3 = powerOperands.begin(); QString op = *it3; bool isNeg = op.startsWith("-"); @@ -667,8 +667,8 @@ void ReUnitParser::parse() { uint64_t exponent = valueOf(*++it3); if (qLn(value) * qLn(exponent) >= qLn(qPow(2.0, 64))) throw ReParserException( - QObject::tr( - "number overflow while power operation")); + QObject::tr( + "number overflow while power operation")); for (int ii = 1; ii < (int) exponent; ii++) value = value * fac; } @@ -707,12 +707,12 @@ uint64_t ReUnitParser::valueOf(const QString& value) const { QStringList pair = it->split(":"); if (pair.count() == 0) throw ReParserException( - QObject::tr( - "missing ':' in unit definition, e.g. 'k:1000': ") - + *it); + QObject::tr( + "missing ':' in unit definition, e.g. 'k:1000': ") + + *it); if (pair.count() > 2) throw ReParserException( - QObject::tr("too many ':' in unit definition: ") + *it); + QObject::tr("too many ':' in unit definition: ") + *it); bool ok = false; QString unit2 = *pair.begin(); QString factor = *++pair.begin(); @@ -727,8 +727,8 @@ uint64_t ReUnitParser::valueOf(const QString& value) const { } if (!found) throw ReParserException( - QObject::tr("unknown unit '$1'. Allowed: ").arg(unit) - + QString(m_unitList)); + QObject::tr("unknown unit '$1'. Allowed: ").arg(unit) + + QString(m_unitList)); } return rc; } @@ -739,10 +739,10 @@ uint64_t ReUnitParser::valueOf(const QString& value) const { * @param expr an expression, e.g. "10*1024kByte+5MiByte" */ ReSizeParser::ReSizeParser(const QString& expr) : - ReUnitParser(expr, "byte:1;kbyte:1000;kibyte:1024;" - "mbyte:1000000;mibyte:1048576;" - "gbyte:1000000000;gibyte:1073741824;" - "tbyte:1000000000000;tibyte:1099511627776") { + ReUnitParser(expr, "byte:1;kbyte:1000;kibyte:1024;" + "mbyte:1000000;mibyte:1048576;" + "gbyte:1000000000;gibyte:1073741824;" + "tbyte:1000000000000;tibyte:1099511627776") { } /** * Constructor. @@ -750,7 +750,7 @@ ReSizeParser::ReSizeParser(const QString& expr) : * @param expr an expression, e.g. "3*3days-5min+3weeks" */ ReDateTimeParser::ReDateTimeParser(const QString& expr) : - ReUnitParser("", "minutes:60;hours:3600;days:86400;weeks:604800", false) { + ReUnitParser("", "minutes:60;hours:3600;days:86400;weeks:604800", false) { parseDateTime(expr); } @@ -786,7 +786,7 @@ QDateTime ReDateTimeParser::parseDateTime(const QString& expr) { if (m_expr.startsWith("now", Qt::CaseInsensitive)) { m_expr.remove(0, 3); } else if ((length2 = ReQStringUtils::lengthOfDateTime(m_expr, 0, true, - true, &dateTime)) > 0) { + true, &dateTime)) > 0) { rc = dateTime; m_expr.remove(0, length2); } else { @@ -806,7 +806,7 @@ QDateTime ReDateTimeParser::parseDateTime(const QString& expr) { } } rc.setMSecsSinceEpoch( - isValid() ? rc.toMSecsSinceEpoch() + 1000 * relativeSeconds : 0); + isValid() ? rc.toMSecsSinceEpoch() + 1000 * relativeSeconds : 0); m_dateTime = rc; return rc; } @@ -814,17 +814,20 @@ QDateTime ReDateTimeParser::parseDateTime(const QString& expr) { /** * Constructor. * - * @param pattern a pattern with wildcards '*' (any string) - * @param anchored true: the pattern starts at the strings start
- * false: the pattern can start anywhere in the string
+ * @param pattern a pattern with wildcards '*' (any string) + * @param caseSensitivity caseSensitive or caseInsensitive + * @param anchored true: the pattern starts at the strings + * start
+ * false: the pattern can start anywhere in + * the string */ ReMatcher::ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensivity, - bool anchored) : - m_needles(), - m_restLengths(), - m_anchored(anchored), - m_caseSensivitiy(caseSensivity) { + bool anchored) : + m_needles(), + m_restLengths(), + m_anchored(anchored), + m_caseSensivitiy(caseSensivity) { setPattern(pattern); } @@ -838,8 +841,8 @@ bool ReMatcher::matches(const QString& text) { bool found = m_needles.size() == 0; if (!found) { found = - m_anchored ? - text.startsWith(m_needles.at(0), m_caseSensivitiy) : true; + m_anchored ? + text.startsWith(m_needles.at(0), m_caseSensivitiy) : true; if (found) { int startIx = m_anchored ? 1 : 0; int textIndex = m_anchored ? m_needles.at(0).length() : 0; @@ -847,7 +850,7 @@ bool ReMatcher::matches(const QString& text) { found = text.size() - textIndex >= m_restLengths.at(ix); if (found) found = (textIndex = text.indexOf(m_needles.at(ix), - textIndex, m_caseSensivitiy)) >= 0; + textIndex, m_caseSensivitiy)) >= 0; } } } @@ -877,3 +880,83 @@ void ReMatcher::setPattern(const QString& pattern) { } +/** + * Constructor. + * + * @param patterns a list of patterns with wildcards '*' (any string) + * @param caseSensitivity caseSensitive or caseInsensitive + * @param anchored true: the pattern starts at the strings + * start
+ * false: the pattern can start anywhere in + * the string + */ +ReListMatcher::ReListMatcher(const QStringList& patterns, + Qt::CaseSensitivity caseSensitivty, bool anchored) : + m_patternList(patterns.size()) +{ + QStringList::const_iterator it; + for (it = patterns.constBegin(); it != patterns.cend(); ++it){ + m_list.append(new ReMatcher(*it, caseSensitivty, anchored)); + } +} +/** + * Destructor. + */ +ReListMatcher::~ReListMatcher(){ + QList::const_iterator it; + for (it = m_list.constBegin(); it != patterns.cend(); ++it){ + delete *it; + } + m_list.clear(); +} +/** + * Tests whether at least one pattern of the list matches the given text + * @param text text to test + * @return true: one of the stored patterns matches the text
+ * false: none of the patterns matches + */ +bool ReListMatcher::matches(const QString& text) +{ + QList::const_iterator it; + bool rc = false; + for (it = m_list.constBegin(); ! rc && it != patterns.cend(); ++it){ + rc = it->matches(text); + } + return rc; +} + +/** + * Constructor. + * + * @param includes a list of include patterns + * @param excludes a list of exclude patterns + * @param caseSensitivity caseSensitive or caseInsensitive + * @param anchored true: the pattern starts at the strings + * start
+ * false: the pattern can start anywhere in + * the string + */ +ReIncludeExcludeMatcher::ReIncludeExcludeMatcher(const QStringList& includes, + const QStringList& excludes, Qt::CaseSensitivity caseSensitivty, + bool anchored) : + m_includes(includes, caseSensitivty, anchored), + m_excludes(excludes, caseSensitivty, anchored) +{ +} + +/** + * Tests whether a text matches the include patterns and does not match the + * exclude patterns. + * + * @param text text to test + * @param excludeToo true: the exclude patterns will be tested + * @return true: at least one of the include patterns + * matches and none of the exclude patterns matches + */ +bool ReIncludeExcludeMatcher::matches(const QString& text, bool excludeToo) +{ + bool rc = m_includes.matches(text); + if (rc && excludeToo && m_excludes.size() > 0) + rc = ! m_excludes.matches(text); + return rc; +} diff --git a/base/ReQStringUtils.hpp b/base/ReQStringUtils.hpp index 443620c..5afb71d 100644 --- a/base/ReQStringUtils.hpp +++ b/base/ReQStringUtils.hpp @@ -12,6 +12,9 @@ #ifndef RPLQSTRING_HPP #define RPLQSTRING_HPP +/** + * Some useful static functions handling QString instances. + */ class ReQStringUtils { public: static ReString chomp(const ReString& text); @@ -19,18 +22,18 @@ public: static QString& ensureLastChar(QString& value, QChar lastChar); static ReString extensionOf(const ReString& filename); static int lengthOfDate(const ReString& text, int start = 0, QDate* value = - NULL); + NULL); static int lengthOfDateTime(const ReString& text, int start = 0, - bool allowDateOnly = true, bool allowTimeOnly = true, QDateTime* value = - NULL); + bool allowDateOnly = true, bool allowTimeOnly = true, QDateTime* value = + NULL); static int lengthOfReal(const ReString& text, int start = 0, qreal* value = - NULL); + NULL); static int lengthOfTime(const ReString& text, int start = 0, QTime* value = - NULL); + NULL); static int lengthOfUInt64(const ReString& text, int start = 0, int radix = - 10, uint64_t* value = NULL); + 10, uint64_t* value = NULL); static int lengthOfUInt(const ReString& text, int start, int radix, - uint* pValue); + uint* pValue); static bool match(const QString& heap, const QStringList& needles); /** * Returns the path with native path separators. @@ -49,9 +52,9 @@ public: static QString pathAppend(const QString& base, const QString& path); static QString replaceExtension(const QString& path, const QString& ext); static bool replacePlaceholders(QString& text, - const QMap& placeholders, QString* error); + const QMap& placeholders, QString* error); static void skipExpected(const ReString& text, QChar expected, int& index, - int& length); + int& length); /** * @brief Returns the value of a hexadecimal digit. * @@ -61,16 +64,24 @@ public: */ inline static int valueOfHexDigit(int digit) { return digit >= '0' && digit <= '9' ? digit - '0' : - digit >= 'A' && digit <= 'F' ? digit - 'A' + 10 : - digit >= 'a' && digit <= 'f' ? digit - 'a' + 10 : -1; + digit >= 'A' && digit <= 'F' ? digit - 'A' + 10 : + digit >= 'a' && digit <= 'f' ? digit - 'a' + 10 : -1; } static char* utf8(const ReString& source, char buffer[], size_t bufferSize); }; +/** + * Calculates expressions with simple arithmetic and units. + * + * Allowed operators are '+', '-', '*', '/' and '^'. + * Parenthesis are not allowed. + * + * Example: 3*7k+8 means 21008 + */ class ReUnitParser { public: ReUnitParser(const QString& expr, const char* unitList, bool parseAtOnce = - true); + true); public: bool isValid() const; const QString& errorMessage() const; @@ -93,6 +104,13 @@ public: ReSizeParser(const QString& expr); }; +/** + * Calculates time expressions. + * + * Syntax: { "now" | [