diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2017-02-07 22:29:45 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2017-04-10 14:54:31 +0000 |
commit | 46c66bce5de04396292600b0c2c87c2468a02102 (patch) | |
tree | b801f976107782b62e305fdb31d1284fe5691803 /src/corelib | |
parent | db29042588ac406b46ec431badc2c12a5d3a8d56 (diff) |
Optimize QLoggingSettingsParser
Factor the line parsing into a separate function, parseNextLine(),
taking a QStringRef.
In setContent(QTextStream&), use the new readLineInto() function to
re-use the capacity of a single QString for all lines.
In setContent(QString), use splitRef() to split the lines.
In either function, pass each line to parseNextLine().
In order to port all the parsing to QStringRef, I needed to make some
semantic changes: the old code removed all whitespace right at the
beginning. This is not possible with QStringRef. It also didn't feel
right, since a line like
[ r u l e s ]
would successfully parse as the section named "rules".
I added trimmed() calls at the beginning, and around the valueStr and
pattern extraction, which should be good enough.
Also, when a section is found, don't store it anymore. Instead, only
store whether it was the [rules] section, because that's all we'll
test for. That way, we don't have to convert QStringRefs to QString
just to store them across parseNextLine() calls.
Replace the setSection() function with setImplicitRulesSection(),
because "rules" is all that was ever passed.
This is private API, we can bring back some of the dropped flexibility
later, as needed.
[ChangeLog][Important Behavior Changes] Logging rules can no longer
contain arbitrary whitespace such as within a category identifier.
Change-Id: Ic26cd23c71f5c810b37ef4b972354ac31d3408fe
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qloggingregistry.cpp | 83 | ||||
-rw-r--r-- | src/corelib/io/qloggingregistry_p.h | 7 |
2 files changed, 51 insertions, 39 deletions
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index ff865dc9a1..47fb1fb6b8 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -186,9 +186,10 @@ void QLoggingRule::parse(const QStringRef &pattern) */ void QLoggingSettingsParser::setContent(const QString &content) { - QString content_ = content; - QTextStream stream(&content_, QIODevice::ReadOnly); - setContent(stream); + _rules.clear(); + const auto lines = content.splitRef(QLatin1Char('\n')); + for (const auto &line : lines) + parseNextLine(line); } /*! @@ -198,42 +199,50 @@ void QLoggingSettingsParser::setContent(const QString &content) void QLoggingSettingsParser::setContent(QTextStream &stream) { _rules.clear(); - while (!stream.atEnd()) { - QString line = stream.readLine(); - - // Remove all whitespace from line - line = line.simplified(); - line.remove(QLatin1Char(' ')); + QString line; + while (stream.readLineInto(&line)) + parseNextLine(QStringRef(&line)); +} - // comment - if (line.startsWith(QLatin1Char(';'))) - continue; +/*! + \internal + Parses one line of the configuation file +*/ - if (line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) { - // new section - _section = line.mid(1, line.size() - 2); - continue; - } +void QLoggingSettingsParser::parseNextLine(QStringRef line) +{ + // Remove whitespace at start and end of line: + line = line.trimmed(); + + // comment + if (line.startsWith(QLatin1Char(';'))) + return; + + if (line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) { + // new section + auto sectionName = line.mid(1, line.size() - 2).trimmed(); + m_inRulesSection = sectionName.compare(QLatin1String("rules"), Qt::CaseInsensitive) == 0; + return; + } - if (_section.compare(QLatin1String("rules"), Qt::CaseInsensitive) == 0) { - int equalPos = line.indexOf(QLatin1Char('=')); - if (equalPos != -1) { - if (line.lastIndexOf(QLatin1Char('=')) == equalPos) { - const QStringRef pattern = line.leftRef(equalPos); - const QStringRef valueStr = line.midRef(equalPos + 1); - int value = -1; - if (valueStr == QLatin1String("true")) - value = 1; - else if (valueStr == QLatin1String("false")) - value = 0; - QLoggingRule rule(pattern, (value == 1)); - if (rule.flags != 0 && (value != -1)) - _rules.append(rule); - else - warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData()); - } else { + if (m_inRulesSection) { + int equalPos = line.indexOf(QLatin1Char('=')); + if (equalPos != -1) { + if (line.lastIndexOf(QLatin1Char('=')) == equalPos) { + const auto pattern = line.left(equalPos).trimmed(); + const auto valueStr = line.mid(equalPos + 1).trimmed(); + int value = -1; + if (valueStr == QLatin1String("true")) + value = 1; + else if (valueStr == QLatin1String("false")) + value = 0; + QLoggingRule rule(pattern, (value == 1)); + if (rule.flags != 0 && (value != -1)) + _rules.append(rule); + else warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData()); - } + } else { + warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData()); } } } @@ -286,7 +295,7 @@ void QLoggingRegistry::init() if (!rulesSrc.isEmpty()) { QTextStream stream(rulesSrc); QLoggingSettingsParser parser; - parser.setSection(QStringLiteral("Rules")); + parser.setImplicitRulesSection(true); parser.setContent(stream); er += parser.rules(); } @@ -350,7 +359,7 @@ void QLoggingRegistry::unregisterCategory(QLoggingCategory *cat) void QLoggingRegistry::setApiRules(const QString &content) { QLoggingSettingsParser parser; - parser.setSection(QStringLiteral("Rules")); + parser.setImplicitRulesSection(true); parser.setContent(content); if (qtLoggingDebug()) diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h index 23740c4955..69fc6ea4ec 100644 --- a/src/corelib/io/qloggingregistry_p.h +++ b/src/corelib/io/qloggingregistry_p.h @@ -93,7 +93,7 @@ Q_DECLARE_TYPEINFO(QLoggingRule, Q_MOVABLE_TYPE); class Q_AUTOTEST_EXPORT QLoggingSettingsParser { public: - void setSection(const QString §ion) { _section = section; } + void setImplicitRulesSection(bool inRulesSection) { m_inRulesSection = inRulesSection; } void setContent(const QString &content); void setContent(QTextStream &stream); @@ -101,7 +101,10 @@ public: QVector<QLoggingRule> rules() const { return _rules; } private: - QString _section; + void parseNextLine(QStringRef line); + +private: + bool m_inRulesSection = false; QVector<QLoggingRule> _rules; }; |