Port to QRegularExpression

Port away from using QRegExp to QRegularExpression. The result is a bit
better performance, a bit more readable code (imho) and also no more
relying on mutable state in static objects (like in the keyboard
translator parser).

REVIEW: 128346
parent 272c8f7f
......@@ -318,11 +318,12 @@ QStringList RegExpFilter::HotSpot::capturedTexts() const
return _capturedTexts;
}
void RegExpFilter::setRegExp(const QRegExp& regExp)
void RegExpFilter::setRegExp(const QRegularExpression &regExp)
{
_searchText = regExp;
_searchText.optimize();
}
QRegExp RegExpFilter::regExp() const
QRegularExpression RegExpFilter::regExp() const
{
return _searchText;
}
......@@ -332,38 +333,33 @@ QRegExp RegExpFilter::regExp() const
}*/
void RegExpFilter::process()
{
int pos = 0;
const QString* text = buffer();
Q_ASSERT(text);
// ignore any regular expressions which match an empty string.
// otherwise the while loop below will run indefinitely
if (_searchText.isEmpty())
if (!_searchText.isValid()) {
return;
}
while (pos >= 0) {
pos = _searchText.indexIn(*text, pos);
if (pos >= 0) {
int startLine = 0;
int endLine = 0;
int startColumn = 0;
int endColumn = 0;
getLineColumn(pos, startLine, startColumn);
getLineColumn(pos + _searchText.matchedLength(), endLine, endColumn);
QRegularExpressionMatchIterator iterator(_searchText.globalMatch(*text));
while (iterator.hasNext()) {
QRegularExpressionMatch match(iterator.next());
if (RegExpFilter::HotSpot* spot = newHotSpot(startLine, startColumn,
endLine, endColumn, _searchText.capturedTexts()))
addHotSpot(spot);
int startLine = 0;
int endLine = 0;
int startColumn = 0;
int endColumn = 0;
pos += _searchText.matchedLength();
getLineColumn(match.capturedStart(), startLine, startColumn);
getLineColumn(match.capturedEnd(), endLine, endColumn);
// if matchedLength == 0, the program will get stuck in an infinite loop
if (_searchText.matchedLength() == 0)
pos = -1;
RegExpFilter::HotSpot* spot = newHotSpot(startLine, startColumn,
endLine, endColumn, match.capturedTexts());
if (!spot) {
continue;
}
addHotSpot(spot);
}
}
......@@ -391,12 +387,13 @@ UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
{
const QString url = capturedTexts().at(0);
if (FullUrlRegExp.exactMatch(url))
if (FullUrlRegExp.match(url).hasMatch()) {
return StandardUrl;
else if (EmailAddressRegExp.exactMatch(url))
} else if (EmailAddressRegExp.match(url).hasMatch()) {
return Email;
else
} else {
return Unknown;
}
}
void UrlFilter::HotSpot::activate(QObject* object)
......@@ -435,14 +432,17 @@ void UrlFilter::HotSpot::activate(QObject* object)
//regexp matches:
// full url:
// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, ), :, comma and dot
const QRegExp UrlFilter::FullUrlRegExp("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]\\)\\:]");
const QRegularExpression UrlFilter::FullUrlRegExp("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]\\)\\:]",
QRegularExpression::OptimizeOnFirstUsageOption);
// email address:
// [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
const QRegExp UrlFilter::EmailAddressRegExp("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b");
const QRegularExpression UrlFilter::EmailAddressRegExp("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b",
QRegularExpression::OptimizeOnFirstUsageOption);
// matches full url or email address
const QRegExp UrlFilter::CompleteUrlRegExp('(' + FullUrlRegExp.pattern() + '|' +
EmailAddressRegExp.pattern() + ')');
const QRegularExpression UrlFilter::CompleteUrlRegExp('(' + FullUrlRegExp.pattern() + '|' +
EmailAddressRegExp.pattern() + ')',
QRegularExpression::OptimizeOnFirstUsageOption);
UrlFilter::UrlFilter()
{
......@@ -536,13 +536,13 @@ FileFilter::FileFilter(Session* session)
patterns.removeDuplicates();
patterns.replaceInStrings("*", "");
patterns = patterns.filter(QRegExp("^[A-Za-z0-9\\._-]+$"));
patterns = patterns.filter(QRegularExpression("^[A-Za-z0-9\\._-]+$"));
patterns.replaceInStrings(".", "\\.");
QString regex("(\\b|/)+[A-Za-z0-9\\._-/]+(");
QString regex("(\\b|/)+[A-Za-z0-9\\._\\-/]+(");
regex.append(patterns.join("|"));
regex.append("){1}\\b");
setRegExp(QRegExp(regex));
setRegExp(QRegularExpression(regex));
}
FileFilter::HotSpot::~HotSpot()
......
......@@ -26,7 +26,7 @@
#include <QtCore/QObject>
#include <QtCore/QPointer>
#include <QtCore/QStringList>
#include <QtCore/QRegExp>
#include <QtCore/QRegularExpression>
#include <QtCore/QMultiHash>
// Konsole
......@@ -212,9 +212,9 @@ public:
* Regular expressions which match the empty string are treated as not matching
* anything.
*/
void setRegExp(const QRegExp& text);
void setRegExp(const QRegularExpression &text);
/** Returns the regular expression which the filter searches for in blocks of text */
QRegExp regExp() const;
QRegularExpression regExp() const;
/**
* Reimplemented to search the filter's text buffer for text matching regExp()
......@@ -233,7 +233,7 @@ protected:
int endLine, int endColumn, const QStringList& capturedTexts);
private:
QRegExp _searchText;
QRegularExpression _searchText;
};
class FilterObject;
......@@ -277,11 +277,11 @@ protected:
virtual RegExpFilter::HotSpot* newHotSpot(int, int, int, int, const QStringList&);
private:
static const QRegExp FullUrlRegExp;
static const QRegExp EmailAddressRegExp;
static const QRegularExpression FullUrlRegExp;
static const QRegularExpression EmailAddressRegExp;
// combined OR of FullUrlRegExp and EmailAddressRegExp
static const QRegExp CompleteUrlRegExp;
static const QRegularExpression CompleteUrlRegExp;
};
/**
......
......@@ -29,6 +29,7 @@
// Qt
#include <QtCore/QBuffer>
#include <QtCore/QTextStream>
#include <QtCore/QRegularExpression>
#include <QtGui/QKeySequence>
// KDE
......@@ -358,39 +359,46 @@ QList<KeyboardTranslatorReader::Token> KeyboardTranslatorReader::tokenize(const
text = text.simplified();
// title line: keyboard "title"
static QRegExp title("keyboard\\s+\"(.*)\"");
static const QRegularExpression title("keyboard\\s+\"(.*)\"", QRegularExpression::OptimizeOnFirstUsageOption);
// key line: key KeySequence : "output"
// key line: key KeySequence : command
static QRegExp key("key\\s+([\\w\\+\\s\\-\\*\\.]+)\\s*:\\s*(\"(.*)\"|\\w+)");
static const QRegularExpression key("key\\s+([\\w\\+\\s\\-\\*\\.]+)\\s*:\\s*(\"(.*)\"|\\w+)", QRegularExpression::OptimizeOnFirstUsageOption);
QList<Token> list;
if (text.isEmpty()) {
return list;
}
if (title.exactMatch(text)) {
QRegularExpressionMatch titleMatch(title.match(text));
if (titleMatch.hasMatch()) {
Token titleToken = { Token::TitleKeyword , QString() };
Token textToken = { Token::TitleText , title.capturedTexts().at(1) };
Token textToken = { Token::TitleText , titleMatch.captured(1) };
list << titleToken << textToken;
} else if (key.exactMatch(text)) {
Token keyToken = { Token::KeyKeyword , QString() };
QString sequenceTokenString = key.capturedTexts().at(1);
Token sequenceToken = { Token::KeySequence , sequenceTokenString.remove(QChar(' ')) };
list << keyToken << sequenceToken;
if (key.capturedTexts().at(3).isEmpty()) {
// capturedTexts().at(2) is a command
Token commandToken = { Token::Command , key.capturedTexts().at(2) };
list << commandToken;
} else {
// capturedTexts().at(3) is the output string
Token outputToken = { Token::OutputText , key.capturedTexts().at(3) };
list << outputToken;
}
} else {
return list;
}
QRegularExpressionMatch keyMatch(key.match(text));
if (!keyMatch.hasMatch()) {
qWarning() << "Line in keyboard translator file could not be understood:" << text;
return list;
}
Token keyToken = { Token::KeyKeyword , QString() };
QString sequenceTokenString = keyMatch.captured(1);
Token sequenceToken = { Token::KeySequence , sequenceTokenString.remove(QChar(' ')) };
list << keyToken << sequenceToken;
if (keyMatch.capturedRef(3).isEmpty()) {
// capturedTexts().at(2) is a command
Token commandToken = { Token::Command , keyMatch.captured(2) };
list << commandToken;
} else {
// capturedTexts().at(3) is the output string
Token outputToken = { Token::OutputText , keyMatch.captured(3) };
list << outputToken;
}
return list;
......
......@@ -24,6 +24,7 @@
// Qt
#include <QtCore/QTextCodec>
#include <QtCore/QRegularExpression>
// KDE
#include <KLocalizedString>
......@@ -317,20 +318,14 @@ QHash<Profile::Property, QVariant> ProfileCommandParser::parse(const QString& in
// where 'property' is a word consisting only of characters from A-Z
// where 'value' is any sequence of characters other than a semi-colon
//
static QRegExp regExp("([a-zA-Z]+)=([^;]+)");
int offset = 0;
while (regExp.indexIn(input, offset) != -1) {
if (regExp.capturedTexts().count() == 3) {
Profile::Property property = Profile::lookupByName(
regExp.capturedTexts().at(1));
const QString value = regExp.capturedTexts().at(2);
changes.insert(property, value);
}
offset = input.indexOf(';', offset) + 1;
if (offset == 0)
break;
static const QRegularExpression regExp("([a-zA-Z]+)=([^;]+)");
QRegularExpressionMatchIterator iterator(regExp.globalMatch(input));
while (iterator.hasNext()) {
QRegularExpressionMatch match(iterator.next());
Profile::Property property = Profile::lookupByName(match.captured(1));
const QString value = match.captured(2);
changes.insert(property, value);
}
return changes;
......
......@@ -1177,14 +1177,23 @@ bool SessionController::reverseSearchChecked() const
return options.at(IncrementalSearchBar::ReverseSearch);
}
QRegExp SessionController::regexpFromSearchBarOptions()
QRegularExpression SessionController::regexpFromSearchBarOptions() const
{
QBitArray options = _searchBar->optionsChecked();
Qt::CaseSensitivity caseHandling = options.at(IncrementalSearchBar::MatchCase) ? Qt::CaseSensitive : Qt::CaseInsensitive;
QRegExp::PatternSyntax syntax = options.at(IncrementalSearchBar::RegExp) ? QRegExp::RegExp : QRegExp::FixedString;
QString text(_searchBar->searchText());
QRegularExpression regExp;
if (options.at(IncrementalSearchBar::RegExp)) {
regExp.setPattern(text);
} else {
regExp.setPattern(QRegularExpression::escape(text));
}
if (!options.at(IncrementalSearchBar::MatchCase)) {
regExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
}
QRegExp regExp(_searchBar->searchText(), caseHandling , syntax);
return regExp;
}
......@@ -1252,7 +1261,7 @@ void SessionController::beginSearch(const QString& text , int direction)
Q_ASSERT(_searchBar);
Q_ASSERT(_searchFilter);
QRegExp regExp = regexpFromSearchBarOptions();
QRegularExpression regExp = regexpFromSearchBarOptions();
_searchFilter->setRegExp(regExp);
if (_searchStartLine == -1) {
......@@ -1263,7 +1272,7 @@ void SessionController::beginSearch(const QString& text , int direction)
}
}
if (!regExp.isEmpty()) {
if (!regExp.pattern().isEmpty()) {
_view->screenWindow()->setCurrentResultLine(-1);
SearchHistoryTask* task = new SearchHistoryTask(this);
......@@ -1814,7 +1823,7 @@ void SearchHistoryTask::executeOnScreenWindow(SessionPtr session , ScreenWindowP
Emulation* emulation = session->emulation();
if (!_regExp.isEmpty()) {
if (!_regExp.pattern().isEmpty()) {
int pos = -1;
const bool forwards = (_direction == ForwardsSearch);
const int lastLine = window->lineCount() - 1;
......@@ -1966,11 +1975,11 @@ SearchHistoryTask::SearchDirection SearchHistoryTask::searchDirection() const
{
return _direction;
}
void SearchHistoryTask::setRegExp(const QRegExp& expression)
void SearchHistoryTask::setRegExp(const QRegularExpression &expression)
{
_regExp = expression;
}
QRegExp SearchHistoryTask::regExp() const
QRegularExpression SearchHistoryTask::regExp() const
{
return _regExp;
}
......
......@@ -27,6 +27,7 @@
#include <QtCore/QPointer>
#include <QtCore/QString>
#include <QtCore/QHash>
#include <QtCore/QRegularExpression>
// KDE
#include <KXMLGUIClient>
......@@ -297,7 +298,7 @@ private:
// direction - value from SearchHistoryTask::SearchDirection enum to specify
// the search direction
void beginSearch(const QString& text , int direction);
QRegExp regexpFromSearchBarOptions();
QRegularExpression regexpFromSearchBarOptions() const;
bool reverseSearchChecked() const;
void setupCommonActions();
void setupExtraActions();
......@@ -500,9 +501,9 @@ public:
void addScreenWindow(Session* session , ScreenWindow* searchWindow);
/** Sets the regular expression which is searched for when execute() is called */
void setRegExp(const QRegExp& regExp);
void setRegExp(const QRegularExpression &regExp);
/** Returns the regular expression which is searched for when execute() is called */
QRegExp regExp() const;
QRegularExpression regExp() const;
/** Specifies the direction to search in when execute() is called. */
void setSearchDirection(SearchDirection direction);
......@@ -531,7 +532,7 @@ private:
void highlightResult(ScreenWindowPtr window , int position);
QMap< SessionPtr , ScreenWindowPtr > _windows;
QRegExp _regExp;
QRegularExpression _regExp;
SearchDirection _direction;
int _startLine;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment