Commit 8d8062fe authored by Ahmad Samir's avatar Ahmad Samir

[DrKonqi] Port QRegExp to QRegularExpression

Summary:
Port QRegExp::exactMatch() by using QRegularExpression::anchoredPattern(),
unless the pattern is already anchored by "^" and "$".

BacktraceLineGdb::parse():
 - set QRegularExpression::DotMatchesEverythingOption, since gdb breaks
   some stack frame lines to mulitple lines for readability, e.g.:
   "#5  0x00007f50e99f776f in QWidget::testAttribute_helper (this=0x6e6440,\n
    attribute=Qt::WA_WState_Created) at kernel/qwidget.cpp:9081\n"
   this matches QRegExp behaviour where a "." char matches new lines by
   default.
 - Use clustering parentheses (?:) so as not to capture groups that aren't
   needed, less bookkeeping for QRegularExpression/PCRE

Replace QRegularExpression with QString comparison, the latter is usually
faster.

All unit tests still pass.

Reviewers: #plasma, davidedmundson, sitter, apol

Reviewed By: sitter

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D28042
parent ce461918
......@@ -22,6 +22,7 @@
#include "bugzillalib.h"
#include <QReadWriteLock>
#include <QRegularExpression>
#include "libbugzilla/clients/commentclient.h"
#include "libbugzilla/connection.h"
......@@ -138,11 +139,10 @@ void BugzillaManager::setFeaturesForVersion(const QString& version)
// the change should actually be implemented.
const int nVersionParts = 3;
QString seps = QLatin1String("[._-]");
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
QStringList digits = version.split(QRegExp(seps), QString::SkipEmptyParts);
QStringList digits = version.split(QRegularExpression(QStringLiteral("[._-]")), QString::SkipEmptyParts);
#else
QStringList digits = version.split(QRegExp(seps), Qt::SkipEmptyParts);
QStringList digits = version.split(QRegularExpression(QStringLiteral("[._-]")), Qt::SkipEmptyParts);
#endif
while (digits.count() < nVersionParts) {
digits << QLatin1String("0");
......
......@@ -17,6 +17,7 @@
*/
#include "gdbhighlighter.h"
#include <QRegularExpression>
#include <QTextDocument>
#include <KColorScheme>
......@@ -51,7 +52,7 @@ void GdbHighlighter::highlightBlock(const QString& text)
int cur = 0;
int next;
int diff;
const QRegExp hexptrPattern(QStringLiteral("0x[0-9a-f]+"), Qt::CaseSensitive, QRegExp::RegExp2);
const static QRegularExpression hexptrPattern(QStringLiteral("0x[0-9a-f]+"));
int lineNr = currentBlock().firstLineNumber();
while ( cur < text.length() ) {
next = text.indexOf(QLatin1Char('\n'), cur);
......@@ -122,12 +123,12 @@ void GdbHighlighter::highlightBlock(const QString& text)
}
}
// highlight hexadecimal ptrs
int idx = 0;
while ((idx = hexptrPattern.indexIn(lineStr, idx)) != -1) {
if (hexptrPattern.cap() == QLatin1String("0x0")) {
setFormat(idx, hexptrPattern.matchedLength(), nullptrFormat);
QRegularExpressionMatchIterator iter = hexptrPattern.globalMatch(lineStr);
while (iter.hasNext()) {
const QRegularExpressionMatch match = iter.next();
if (match.captured(0) == QLatin1String("0x0")) {
setFormat(match.capturedStart(0), match.capturedLength(0), nullptrFormat);
}
idx += hexptrPattern.matchedLength();
}
}
......
......@@ -22,7 +22,8 @@
#include "backtraceparsercdb.h"
#include "backtraceparsernull.h"
#include "drkonqi_parser_debug.h"
#include <QRegExp>
#include <QRegularExpression>
#include <QMetaEnum>
//factory
......@@ -145,24 +146,25 @@ static bool lineIsStackBase(const BacktraceLine & line)
|| line.rating() == BacktraceLine::MissingFunction )
return false;
//this is the base frame for all threads except the main thread
//FIXME that probably works only on linux
if ( line.functionName() == QLatin1String("start_thread") )
return true;
QRegExp regExp;
regExp.setPattern(QStringLiteral("(kde)?main")); //main() or kdemain() is the base for the main thread
if ( regExp.exactMatch(line.functionName()) )
// "start_thread" is the base frame for all threads except the main thread, FIXME "start_thread"
// probably works only on linux
// main() or kdemain() is the base for the main thread
if (line.functionName() == QLatin1String("start_thread")
|| line.functionName() == QLatin1String("main")
|| line.functionName() == QLatin1String("kdemain")) {
return true;
}
//HACK for better rating. we ignore all stack frames below any function that matches
//the following regular expression. The functions that match this expression are usually
//"QApplicationPrivate::notify_helper", "QApplication::notify" and similar, which
//are used to send any kind of event to the Qt application. All stack frames below this,
//with or without debug symbols, are useless to KDE developers, so we ignore them.
regExp.setPattern(QStringLiteral("(Q|K)(Core)?Application(Private)?::notify.*"));
if ( regExp.exactMatch(line.functionName()) )
const QRegularExpression re(QRegularExpression::anchoredPattern(
QStringLiteral("(Q|K)(Core)?Application(Private)?::notify.*")));
if (re.match(line.functionName()).hasMatch()) {
return true;
}
//attempt to recognize crashes that happen after main has returned (bug 200993)
if ( line.functionName() == QLatin1String("~KCleanUpGlobalStatic") ||
......
......@@ -18,8 +18,9 @@
#include "backtraceparsergdb.h"
#include "backtraceparser_p.h"
#include "drkonqi_parser_debug.h"
#include <QRegExp>
#include <QFileInfo>
#include <QRegularExpression>
//BEGIN BacktraceLineGdb
......@@ -36,7 +37,6 @@ BacktraceLineGdb::BacktraceLineGdb(const QString & lineStr)
void BacktraceLineGdb::parse()
{
QRegExp regExp;
if (d->m_line == QLatin1Char('\n')) {
d->m_type = EmptyLine;
......@@ -49,14 +49,20 @@ void BacktraceLineGdb::parse()
return;
}
regExp.setPattern(QStringLiteral("^#([0-9]+)" //matches the stack frame number, ex. "#0"
"[\\s]+(0x[0-9a-f]+[\\s]+in[\\s]+)?" // matches " 0x0000dead in " (optionally)
"((\\(anonymous namespace\\)::)?[^\\(]+)?" //matches the function name
static QRegularExpression regExp;
// make dot "." char match new lines, to match e.g.:
// "#5 0x00007f50e99f776f in QWidget::testAttribute_helper (this=0x6e6440,\n attribute=Qt::WA_WState_Created) at kernel/qwidget.cpp:9081\n"
// gdb breaks long stack frame lines into multiple ones for readability
regExp.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
regExp.setPattern(QStringLiteral(
"^#([0-9]+)" //matches the stack frame number, ex. "#0"
"[\\s]+(?:0x[0-9a-f]+[\\s]+in[\\s]+)?" // matches " 0x0000dead in " (optionally)
"((?:\\(anonymous namespace\\)::)?[^\\(]+)?" //matches the function name
//(anything except left parenthesis, which is the start of the arguments section)
//and optionally the prefix "(anonymous namespace)::"
"(\\(.*\\))?" //matches the function arguments
"(?:\\(.*\\))?" //matches the function arguments
//(when the app doesn't have debugging symbols)
"[\\s]+(const[\\s]+)?" //matches a traling const, if it exists
"[\\s]+(?:const[\\s]+)?" //matches a traling const, if it exists
"\\(.*\\)" //matches the arguments of the function with their values
//(when the app has debugging symbols)
"([\\s]+" //beginning of optional file information
......@@ -66,22 +72,23 @@ void BacktraceLineGdb::parse()
//the )? at the end closes the parenthesis before [\\s]+(from|at) and
//notes that the whole expression from there is optional.
if (regExp.exactMatch(d->m_line)) {
QRegularExpressionMatch match = regExp.match(d->m_line);
if (match.hasMatch()) {
d->m_type = StackFrame;
d->m_stackFrameNumber = regExp.cap(1).toInt();
d->m_functionName = regExp.cap(3).trimmed();
d->m_stackFrameNumber = match.captured(1).toInt();
d->m_functionName = match.captured(2).trimmed();
if (!regExp.cap(7).isEmpty()) { //we have file information (stuff after from|at)
bool file = regExp.cap(8) == QLatin1String("at"); //'at' means we have a source file (likely)
if (!match.captured(3).isEmpty()) { //we have file information (stuff after from|at)
bool file = match.captured(4) == QLatin1String("at"); //'at' means we have a source file (likely)
// Gdb isn't entirely consistent here, when it uses 'from' it always refers to a library, but
// sometimes the stack can resolve to a library even when it uses the 'at' key word.
// This specifically seems to happen when a frame has no function name.
const QString path = regExp.cap(9);
const QString path = match.captured(5);
file = file && !QFileInfo(path).completeSuffix().contains(QLatin1String(".so"));
if (file) {
d->m_file = regExp.cap(9);
d->m_file = match.captured(5);
} else { //'from' means we have a library
d->m_library = regExp.cap(9);
d->m_library = match.captured(5);
}
}
......@@ -94,21 +101,21 @@ void BacktraceLineGdb::parse()
".*\\[New .*|"
"0x[0-9a-f]+.*|"
"Current language:.*"));
if (regExp.exactMatch(d->m_line)) {
if (regExp.match(d->m_line).hasMatch()) {
qCDebug(DRKONQI_PARSER_LOG) << "garbage detected:" << d->m_line;
d->m_type = Crap;
return;
}
regExp.setPattern(QStringLiteral("Thread [0-9]+\\s+\\(Thread [0-9a-fx]+\\s+\\(.*\\)\\):\n"));
if (regExp.exactMatch(d->m_line)) {
if (regExp.match(d->m_line).hasMatch()) {
qCDebug(DRKONQI_PARSER_LOG) << "thread start detected:" << d->m_line;
d->m_type = ThreadStart;
return;
}
regExp.setPattern(QStringLiteral("\\[Current thread is [0-9]+ \\(.*\\)\\]\n"));
if (regExp.exactMatch(d->m_line)) {
if (regExp.match(d->m_line).hasMatch()) {
qCDebug(DRKONQI_PARSER_LOG) << "thread indicator detected:" << d->m_line;
d->m_type = ThreadIndicator;
return;
......
......@@ -19,6 +19,8 @@
#include "backtraceparser_p.h"
#include "drkonqi_parser_debug.h"
#include <QRegularExpression>
//BEGIN BacktraceLineKdbgwin
class BacktraceLineKdbgwin : public BacktraceLine
......@@ -54,17 +56,18 @@ void BacktraceLineKdbgwin::parse()
return;
}
QRegExp regExp;
regExp.setPattern(QStringLiteral("([^!]+)!" //match the module name, followed by !
"([^\\(]+)\\(\\) " //match the function name, followed by ()
"\\[([^@]+)@ [\\-\\d]+\\] " // [filename @ line]
"at 0x.*")); //at 0xdeadbeef
static const QRegularExpression re(QRegularExpression::anchoredPattern(QStringLiteral(
"([^!]+)!" //match the module name, followed by !
"([^\\(]+)\\(\\) " //match the function name, followed by ()
"\\[([^@]+)@ [\\-\\d]+\\] " // [filename @ line]
"at 0x.*"))); //at 0xdeadbeef
if (regExp.exactMatch(d->m_line)) {
const QRegularExpressionMatch match = re.match(d->m_line);
if (match.hasMatch()) {
d->m_type = StackFrame;
d->m_library = regExp.cap(1);
d->m_functionName = regExp.cap(2);
d->m_file = regExp.cap(3).trimmed();
d->m_library = match.captured(1);
d->m_functionName = match.captured(2);
d->m_file = match.captured(3).trimmed();
qCDebug(DRKONQI_PARSER_LOG) << d->m_functionName << d->m_file << d->m_library;
return;
......
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