#include "xmlprotocol/modelhelpers.h"
#include "xmlprotocol/suppression.h"
-#include <texteditor/basetexteditor.h>
-
+#include <coreplugin/coreconstants.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
-#include <coreplugin/coreconstants.h>
-
+#include <texteditor/basetexteditor.h>
#include <utils/qtcassert.h>
#include <QtCore/QDir>
#include <QtCore/QDebug>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
#include <QtGui/QLabel>
#include <QtGui/QListView>
+#include <QtGui/QMenu>
#include <QtGui/QPainter>
#include <QtGui/QScrollBar>
#include <QtGui/QSortFilterProxyModel>
+#include <QtGui/QStyledItemDelegate>
#include <QtGui/QVBoxLayout>
-#include <QtGui/QAction>
-#include <QtGui/QClipboard>
-#include <QtGui/QApplication>
-#include <QtGui/QMenu>
using namespace Valgrind::XmlProtocol;
namespace Valgrind {
namespace Internal {
+class MemcheckErrorDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ /// This delegate can only work on one view at a time, parent. parent will also be the parent
+ /// in the QObject parent-child system.
+ explicit MemcheckErrorDelegate(QListView *parent);
+
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+public slots:
+ void currentChanged(const QModelIndex &now, const QModelIndex &previous);
+ void viewResized();
+ void layoutChanged();
+ void copy();
+
+private slots:
+ void verticalScrolled();
+ void openLinkInEditor(const QString &link);
+
+private:
+ // the constness of this method is a necessary lie because it is called from paint() const.
+ QWidget *createDetailsWidget(const QModelIndex &errorIndex, QWidget *parent) const;
+
+ static const int s_itemMargin = 2;
+ mutable QPersistentModelIndex m_detailsIndex;
+ mutable QWidget *m_detailsWidget;
+ mutable int m_detailsWidgetHeight;
+};
+
MemcheckErrorDelegate::MemcheckErrorDelegate(QListView *parent)
: QStyledItemDelegate(parent),
m_detailsWidget(0)
const QListView *view = qobject_cast<const QListView *>(parent());
const int viewportWidth = view->viewport()->width();
const bool isSelected = view->selectionModel()->currentIndex() == index;
-
- int dy = 2 * s_itemMargin;
+ const int dy = 2 * s_itemMargin;
if (!isSelected) {
QFontMetrics fm(opt.font);
return QString("0x%1").arg(frame.instructionPointer(), 0, 16);
}
-QString relativeToPath()
+static QString relativeToPath()
{
- // project for which we insert the snippet
+ // The project for which we insert the snippet.
const ProjectExplorer::Project *project =
ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject();
- QString relativeTo( project ? project->projectDirectory() : QDir::homePath() );
+ QString relativeTo(project ? project->projectDirectory() : QDir::homePath());
if (!relativeTo.endsWith(QDir::separator()))
relativeTo.append(QDir::separator());
return relativeTo;
}
-QString errorLocation(const QModelIndex &index, const Error &error,
+static QString errorLocation(const QModelIndex &index, const Error &error,
bool link = false, const QString &linkAttr = QString())
{
const ErrorListModel *model = 0;
// don't include frameName here as it should wrap if required and pre-line is not supported
// by Qt yet it seems
const QString displayTextTemplate = QString("<code style='white-space:pre'>%1:</code> %2");
-
- QString relativeTo = relativeToPath();
-
+ const QString relativeTo = relativeToPath();
const Error error = errorIndex.data(ErrorListModel::ErrorRole).value<Error>();
QLabel *errorLabel = new QLabel();
} // namespace Internal
} // namespace Valgrind
+
+#include "memcheckerrorview.moc"
class Parser::Private
{
- Parser *const q;
public:
explicit Private(Parser *qq);
void parse(QIODevice *device);
+ QString errorString;
- void parse_error();
+private:
+ void parseError();
QVector<Frame> parseStack();
Suppression parseSuppression();
SuppressionFrame parseSuppressionFrame();
- Frame parse_frame();
- void parse_status();
- void parse_errorcounts();
- void parse_suppcounts();
- void parse_announcethread();
+ Frame parseFrame();
+ void parseStatus();
+ void parseErrorCounts();
+ void parseSuppressionCounts();
+ void parseAnnounceThread();
void checkProtocolVersion(const QString &versionStr);
void checkTool(const QString &tool);
XWhat parseXWhat();
QString blockingReadElementText();
Tool tool;
- QString errorString;
QXmlStreamReader reader;
- QHash<QString,MemcheckErrorKind> errorKindsByName_memcheck;
- QHash<QString,HelgrindErrorKind> errorKindsByName_helgrind;
- QHash<QString,PtrcheckErrorKind> errorKindsByName_ptrcheck;
- QHash<QString,Parser::Tool> toolsByName;
+ QHash<QString, MemcheckErrorKind> errorKindsByName_memcheck;
+ QHash<QString, HelgrindErrorKind> errorKindsByName_helgrind;
+ QHash<QString, PtrcheckErrorKind> errorKindsByName_ptrcheck;
+ QHash<QString, Parser::Tool> toolsByName;
+
+private:
+ Parser *const q;
};
#undef ADD_ENUM
Parser::Private::Private(Parser *qq)
- : q(qq),
- tool(Parser::Unknown)
+ : q(qq)
{
+ tool = Parser::Unknown;
toolsByName.insert(QLatin1String("memcheck"), Parser::Memcheck);
toolsByName.insert(QLatin1String("ptrcheck"), Parser::Ptrcheck);
toolsByName.insert(QLatin1String("exp-ptrcheck"), Parser::Ptrcheck);
blockingReadNext();
if (reader.isEndElement())
break;
- if (reader.name() == QLatin1String("text"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("text"))
what.text = blockingReadElementText();
- else if (reader.name() == QLatin1String("leakedbytes"))
+ else if (name == QLatin1String("leakedbytes"))
what.leakedbytes = parseInt64(blockingReadElementText(), QLatin1String("error/xwhat[memcheck]/leakedbytes"));
- else if (reader.name() == QLatin1String("leakedblocks"))
+ else if (name == QLatin1String("leakedblocks"))
what.leakedblocks = parseInt64(blockingReadElementText(), QLatin1String("error/xwhat[memcheck]/leakedblocks"));
- else if (reader.name() == QLatin1String("hthreadid"))
+ else if (name == QLatin1String("hthreadid"))
what.hthreadid = parseInt64(blockingReadElementText(), QLatin1String("error/xwhat[memcheck]/hthreadid"));
else if (reader.isStartElement())
reader.skipCurrentElement();
blockingReadNext();
if (reader.isEndElement())
break;
- if (reader.name() == QLatin1String("text"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("text"))
what.text = blockingReadElementText();
- else if (reader.name() == QLatin1String("file"))
+ else if (name == QLatin1String("file"))
what.file = blockingReadElementText();
- else if (reader.name() == QLatin1String("dir"))
+ else if (name == QLatin1String("dir"))
what.dir = blockingReadElementText();
- else if (reader.name() == QLatin1String("line"))
+ else if (name == QLatin1String("line"))
what.line = parseInt64(blockingReadElementText(), QLatin1String("error/xauxwhat/line"));
- else if (reader.name() == QLatin1String("hthreadid"))
+ else if (name == QLatin1String("hthreadid"))
what.hthreadid = parseInt64(blockingReadElementText(), QLatin1String("error/xauxwhat/hthreadid"));
else if (reader.isStartElement())
reader.skipCurrentElement();
return s;
}
-void Parser::Private::parse_error()
+void Parser::Private::parseError()
{
Error e;
QVector<QVector<Frame> > frames;
break;
if (reader.isStartElement())
lastAuxWhat++;
- if (reader.name() == QLatin1String("unique"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("unique"))
e.setUnique(parseHex(blockingReadElementText(), QLatin1String("unique")));
- else if ( reader.name() == QLatin1String("tid"))
+ else if (name == QLatin1String("tid"))
e.setTid(parseInt64(blockingReadElementText(), QLatin1String("error/tid")));
- else if (reader.name() == QLatin1String("kind")) //TODO this is memcheck-specific:
+ else if (name == QLatin1String("kind")) //TODO this is memcheck-specific:
e.setKind(parseErrorKind(blockingReadElementText()));
- else if (reader.name() == QLatin1String("suppression"))
+ else if (name == QLatin1String("suppression"))
e.setSuppression(parseSuppression());
- else if (reader.name() == QLatin1String("xwhat")) {
+ else if (name == QLatin1String("xwhat")) {
const XWhat xw = parseXWhat();
e.setWhat(xw.text);
e.setLeakedBlocks(xw.leakedblocks);
e.setLeakedBytes(xw.leakedbytes);
e.setHelgrindThreadId(xw.hthreadid);
}
- else if (reader.name() == QLatin1String("what"))
+ else if (name == QLatin1String("what"))
e.setWhat(blockingReadElementText());
- else if (reader.name() == QLatin1String("xauxwhat")) {
+ else if (name == QLatin1String("xauxwhat")) {
if (!currentAux.text.isEmpty())
auxs.push_back(currentAux);
currentAux = parseXauxWhat();
}
- else if (reader.name() == QLatin1String("auxwhat")) {
+ else if (name == QLatin1String("auxwhat")) {
const QString aux = blockingReadElementText();
//concatenate multiple consecutive <auxwhat> tags
if (lastAuxWhat > 1) {
}
lastAuxWhat = 0;
}
- else if (reader.name() == QLatin1String("stack")) {
+ else if (name == QLatin1String("stack")) {
frames.push_back(parseStack());
}
else if (reader.isStartElement())
emit q->error(e);
}
-Frame Parser::Private::parse_frame()
+Frame Parser::Private::parseFrame()
{
Frame frame;
if (reader.isEndElement())
break;
if (reader.isStartElement()) {
- if (reader.name() == QLatin1String("ip"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("ip"))
frame.setInstructionPointer(parseHex(blockingReadElementText(), QLatin1String("error/frame/ip")));
- else if (reader.name() == QLatin1String("obj"))
+ else if (name == QLatin1String("obj"))
frame.setObject(blockingReadElementText());
- else if (reader.name() == QLatin1String("fn"))
+ else if (name == QLatin1String("fn"))
frame.setFunctionName( blockingReadElementText());
- else if (reader.name() == QLatin1String("dir"))
+ else if (name == QLatin1String("dir"))
frame.setDirectory(blockingReadElementText());
- else if (reader.name() == QLatin1String("file"))
+ else if (name == QLatin1String("file"))
frame.setFile( blockingReadElementText());
- else if (reader.name() == QLatin1String("line"))
+ else if (name == QLatin1String("line"))
frame.setLine(parseInt64(blockingReadElementText(), QLatin1String("error/frame/line")));
else if (reader.isStartElement())
reader.skipCurrentElement();
return frame;
}
-void Parser::Private::parse_announcethread()
+void Parser::Private::parseAnnounceThread()
{
AnnounceThread at;
if (reader.isEndElement())
break;
if (reader.isStartElement()) {
- if (reader.name() == QLatin1String("hthreadid"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("hthreadid"))
at.setHelgrindThreadId(parseInt64(blockingReadElementText(), QLatin1String("announcethread/hthreadid")));
- else if (reader.name() == QLatin1String("stack"))
+ else if (name == QLatin1String("stack"))
at.setStack(parseStack());
else if (reader.isStartElement())
reader.skipCurrentElement();
emit q->announceThread(at);
}
-void Parser::Private::parse_errorcounts()
+void Parser::Private::parseErrorCounts()
{
while (notAtEnd()) {
blockingReadNext();
if (reader.isEndElement())
break;
if (reader.isStartElement()) {
- if (reader.name() == QLatin1String("unique"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("unique"))
unique = parseHex(blockingReadElementText(), QLatin1String("errorcounts/pair/unique"));
- else if (reader.name() == QLatin1String("count"))
+ else if (name == QLatin1String("count"))
count = parseInt64(blockingReadElementText(), QLatin1String("errorcounts/pair/count"));
else if (reader.isStartElement())
reader.skipCurrentElement();
}
-void Parser::Private::parse_suppcounts()
+void Parser::Private::parseSuppressionCounts()
{
while (notAtEnd()) {
blockingReadNext();
break;
if (reader.isStartElement()) {
if (reader.name() == QLatin1String("pair")) {
- QString name;
+ QString pairName;
qint64 count = 0;
while (notAtEnd()) {
blockingReadNext();
if (reader.isEndElement())
break;
if (reader.isStartElement()) {
- if (reader.name() == QLatin1String("name"))
- name = blockingReadElementText();
- else if (reader.name() == QLatin1String("count"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("name"))
+ pairName = blockingReadElementText();
+ else if (name == QLatin1String("count"))
count = parseInt64(blockingReadElementText(), QLatin1String("suppcounts/pair/count"));
else if (reader.isStartElement())
reader.skipCurrentElement();
}
}
- emit q->suppressionCount(name, count);
+ emit q->suppressionCount(pairName, count);
}
else if (reader.isStartElement())
reader.skipCurrentElement();
}
}
-void Parser::Private::parse_status()
+void Parser::Private::parseStatus()
{
Status s;
if (reader.isEndElement())
break;
if (reader.isStartElement()) {
- if (reader.name() == QLatin1String("state"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("state"))
s.setState(parseState(blockingReadElementText()));
- else if (reader.name() == QLatin1String("time"))
+ else if (name == QLatin1String("time"))
s.setTime(blockingReadElementText());
else if (reader.isStartElement())
reader.skipCurrentElement();
break;
if (reader.isStartElement()) {
if (reader.name() == QLatin1String("frame"))
- frames.append(parse_frame());
+ frames.append(parseFrame());
}
}
if (reader.isEndElement())
break;
if (reader.isStartElement()) {
- if (reader.name() == QLatin1String("obj"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("obj"))
frame.setObject(blockingReadElementText());
- else if (reader.name() == QLatin1String("fun"))
+ else if (name == QLatin1String("fun"))
frame.setFunction( blockingReadElementText());
else if (reader.isStartElement())
reader.skipCurrentElement();
if (reader.isEndElement())
break;
if (reader.isStartElement()) {
- if (reader.name() == QLatin1String("sname"))
+ const QStringRef name = reader.name();
+ if (name == QLatin1String("sname"))
supp.setName(blockingReadElementText());
- else if (reader.name() == QLatin1String("skind"))
+ else if (name == QLatin1String("skind"))
supp.setKind(blockingReadElementText());
- else if (reader.name() == QLatin1String("skaux"))
+ else if (name == QLatin1String("skaux"))
supp.setAuxKind(blockingReadElementText());
- else if (reader.name() == QLatin1String("rawtext"))
+ else if (name == QLatin1String("rawtext"))
supp.setRawText(blockingReadElementText());
- else if (reader.name() == QLatin1String("sframe"))
+ else if (name == QLatin1String("sframe"))
frames.push_back(parseSuppressionFrame());
}
}
try {
while (notAtEnd()) {
blockingReadNext();
- if (reader.name() == QLatin1String("error"))
- parse_error();
- else if (reader.name() == QLatin1String("announcethread"))
- parse_announcethread();
- else if (reader.name() == QLatin1String("status"))
- parse_status();
- else if (reader.name() == QLatin1String("errorcounts"))
- parse_errorcounts();
- else if (reader.name() == QLatin1String("suppcounts"))
- parse_suppcounts();
- else if (reader.name() == QLatin1String("protocolversion"))
+ QStringRef name = reader.name();
+ if (name == QLatin1String("error"))
+ parseError();
+ else if (name == QLatin1String("announcethread"))
+ parseAnnounceThread();
+ else if (name == QLatin1String("status"))
+ parseStatus();
+ else if (name == QLatin1String("errorcounts"))
+ parseErrorCounts();
+ else if (name == QLatin1String("suppcounts"))
+ parseSuppressionCounts();
+ else if (name == QLatin1String("protocolversion"))
checkProtocolVersion(blockingReadElementText());
- else if (reader.name() == QLatin1String("protocoltool"))
+ else if (name == QLatin1String("protocoltool"))
checkTool(blockingReadElementText());
}
} catch (const ParserException &e) {