mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
141 lines
5.7 KiB
C++
141 lines
5.7 KiB
C++
/*
|
|
Copyright (C) 2010 Milian Wolff <mail@milianw.de>
|
|
|
|
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.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
#include "gdbhighlighter.h"
|
|
|
|
#include <QTextDocument>
|
|
|
|
#include <KColorScheme>
|
|
|
|
GdbHighlighter::GdbHighlighter(QTextDocument* parent, const QList<BacktraceLine> & gdbLines)
|
|
: QSyntaxHighlighter(parent)
|
|
{
|
|
// setup line lookup
|
|
int l = 0;
|
|
foreach(const BacktraceLine& line, gdbLines) {
|
|
lines.insert(l, line);
|
|
l += line.toString().count('\n');
|
|
}
|
|
// Add a dummy, in case the last backtrace line has more than 1 '\n' char.
|
|
const BacktraceLine dummy;
|
|
lines.insert(l, dummy);
|
|
|
|
// setup formates
|
|
KColorScheme scheme(QPalette::Active);
|
|
|
|
crashFormat.setForeground(scheme.foreground(KColorScheme::NegativeText));
|
|
nullptrFormat.setForeground(scheme.foreground(KColorScheme::NegativeText));
|
|
nullptrFormat.setFontWeight(QFont::Bold);
|
|
assertFormat = nullptrFormat;
|
|
threadFormat.setForeground(scheme.foreground(KColorScheme::NeutralText));
|
|
urlFormat.setForeground(scheme.foreground(KColorScheme::LinkText));
|
|
funcFormat.setForeground(scheme.foreground(KColorScheme::VisitedText));
|
|
funcFormat.setFontWeight(QFont::Bold);
|
|
otheridFormat.setForeground(scheme.foreground(KColorScheme::PositiveText));
|
|
crapFormat.setForeground(scheme.foreground(KColorScheme::InactiveText));
|
|
}
|
|
|
|
void GdbHighlighter::highlightBlock(const QString& text)
|
|
{
|
|
int cur = 0;
|
|
int next;
|
|
int diff;
|
|
const QRegExp hexptrPattern("0x[0-9a-f]+", Qt::CaseSensitive, QRegExp::RegExp2);
|
|
int lineNr = currentBlock().firstLineNumber();
|
|
while ( cur < text.length() ) {
|
|
next = text.indexOf('\n', cur);
|
|
if (next == -1) {
|
|
next = text.length();
|
|
}
|
|
if (lineNr == 0) {
|
|
// line that contains 'Application: ...'
|
|
++lineNr;
|
|
cur = next;
|
|
continue;
|
|
}
|
|
|
|
diff = next - cur;
|
|
|
|
QString lineStr = text.mid(cur, diff).append('\n');
|
|
// -1 since we skip the first line
|
|
QMap< int, BacktraceLine >::iterator it = lines.lowerBound(lineNr - 1);
|
|
Q_ASSERT(it != lines.end());
|
|
// QMap::lowerBound() returns the next higher item or
|
|
// the dummy item, but we want the one before that.
|
|
if (it.key() > lineNr - 1) {
|
|
--it;
|
|
}
|
|
const BacktraceLine& line = it.value();
|
|
|
|
if (line.type() == BacktraceLine::KCrash) {
|
|
setFormat(cur, diff, crashFormat);
|
|
} else if (line.type() == BacktraceLine::ThreadStart || line.type() == BacktraceLine::ThreadIndicator) {
|
|
setFormat(cur, diff, threadFormat);
|
|
} else if (line.type() == BacktraceLine::Crap) {
|
|
setFormat(cur, diff, crapFormat);
|
|
} else if (line.type() == BacktraceLine::StackFrame) {
|
|
if (!line.fileName().isEmpty()) {
|
|
int colonPos = line.fileName().lastIndexOf(':');
|
|
setFormat(lineStr.indexOf(line.fileName()), colonPos == -1 ? line.fileName().length() : colonPos, urlFormat);
|
|
}
|
|
if (!line.libraryName().isEmpty()) {
|
|
setFormat(lineStr.indexOf(line.libraryName()), line.libraryName().length(), urlFormat);
|
|
}
|
|
if (!line.functionName().isEmpty()) {
|
|
int idx = lineStr.indexOf(line.functionName());
|
|
if (idx != -1) {
|
|
// highlight Id::Id::Id::Func
|
|
// Id should have otheridFormat, :: no format and Func funcFormat
|
|
int i = idx;
|
|
int from = idx;
|
|
while (i < idx + line.functionName().length()) {
|
|
if (lineStr.at(i) == ':') {
|
|
setFormat(from, i - from, otheridFormat);
|
|
// skip ::
|
|
i += 2;
|
|
from = i;
|
|
continue;
|
|
} else if (lineStr.at(i) == '<' || lineStr.at(i) == '>') {
|
|
setFormat(from, i - from, otheridFormat);
|
|
++i;
|
|
from = i;
|
|
continue;
|
|
}
|
|
++i;
|
|
}
|
|
if (line.functionName() == "qFatal" || line.functionName() == "abort" || line.functionName() == "__assert_fail"
|
|
|| line.functionName() == "*__GI___assert_fail" || line.functionName() == "*__GI_abort") {
|
|
setFormat(from, i - from, assertFormat);
|
|
} else {
|
|
setFormat(from, i - from, funcFormat);
|
|
}
|
|
}
|
|
}
|
|
// highlight hexadecimal ptrs
|
|
int idx = 0;
|
|
while ((idx = hexptrPattern.indexIn(lineStr, idx)) != -1) {
|
|
if (hexptrPattern.cap() == "0x0") {
|
|
setFormat(idx, hexptrPattern.matchedLength(), nullptrFormat);
|
|
}
|
|
idx += hexptrPattern.matchedLength();
|
|
}
|
|
}
|
|
|
|
cur = next;
|
|
++lineNr;
|
|
}
|
|
}
|