set(qapitrace_SRCS
+ apitracecall.cpp
+ apitracefilter.cpp
apitracemodel.cpp
loaderthread.cpp
mainwindow.cpp
--- /dev/null
+#include "apitracecall.h"
+
+#include "trace_model.hpp"
+
+#include <QDebug>
+
+ApiPointer::ApiPointer(int val)
+ : m_value(val)
+{
+}
+
+QString ApiPointer::toString() const
+{
+ if (m_value)
+ return QString("0x%1").arg(m_value, 0, 16);
+ else
+ return QLatin1String("NULL");
+}
+
+QString apiVariantToString(const QVariant &variant)
+{
+ if (variant.userType() == QVariant::Double) {
+ return QString::number(variant.toFloat());
+ }
+
+ if (variant.userType() < QVariant::UserType) {
+ return variant.toString();
+ }
+
+ if (variant.canConvert<ApiPointer>()) {
+ return variant.value<ApiPointer>().toString();
+ }
+ if (variant.canConvert<ApiBitmask>()) {
+ return variant.value<ApiBitmask>().toString();
+ }
+ if (variant.canConvert<ApiStruct>()) {
+ return variant.value<ApiStruct>().toString();
+ }
+ if (variant.canConvert<ApiArray>()) {
+ return variant.value<ApiArray>().toString();
+ }
+
+ return QString();
+}
+
+ApiBitmask::ApiBitmask(const Trace::Bitmask *bitmask)
+ : m_value(0)
+{
+ init(bitmask);
+}
+
+
+void ApiBitmask::init(const Trace::Bitmask *bitmask)
+{
+ if (!bitmask)
+ return;
+
+ m_value = bitmask->value;
+ for (Trace::Bitmask::Signature::const_iterator it = bitmask->sig->begin();
+ it != bitmask->sig->end(); ++it) {
+ assert(it->second);
+ QPair<QString, unsigned long long> pair;
+
+ pair.first = QString::fromStdString(it->first);
+ pair.second = it->second;
+
+ m_sig.append(pair);
+ }
+}
+
+QString ApiBitmask::toString() const
+{
+ QString str;
+ unsigned long long value = m_value;
+ bool first = true;
+ for (Signature::const_iterator it = m_sig.begin();
+ value != 0 && it != m_sig.end(); ++it) {
+ Q_ASSERT(it->second);
+ if ((value & it->second) == it->second) {
+ if (!first) {
+ str += QLatin1String(" | ");
+ }
+ str += it->first;
+ value &= ~it->second;
+ first = false;
+ }
+ }
+ if (value || first) {
+ if (!first) {
+ str += QLatin1String(" | ");
+ }
+ str += QString::fromLatin1("0x%1").arg(value, 0, 16);
+ }
+ return str;
+}
+
+ApiStruct::ApiStruct(const Trace::Struct *s)
+{
+ init(s);
+}
+
+QString ApiStruct::toString() const
+{
+ QString str;
+
+ str += QLatin1String("{");
+ for (unsigned i = 0; i < m_members.count(); ++i) {
+ str += m_sig.memberNames[i];
+ str += QLatin1String(" = ");
+ str += apiVariantToString(m_members[i]);
+ if (i < m_members.count() - 1)
+ str += QLatin1String(", ");
+ }
+ str += QLatin1String("}");
+
+ return str;
+}
+
+void ApiStruct::init(const Trace::Struct *s)
+{
+ if (!s)
+ return;
+
+ m_sig.name = QString::fromStdString(s->sig->name);
+ for (unsigned i = 0; i < s->members.size(); ++i) {
+ VariantVisitor vis;
+ m_sig.memberNames.append(
+ QString::fromStdString(s->sig->member_names[i]));
+ s->members[i]->visit(vis);
+ m_members.append(vis.variant());
+ }
+}
+
+void VariantVisitor::visit(Trace::Null *)
+{
+ m_variant = QVariant(QLatin1String("NULL"));
+}
+
+void VariantVisitor::visit(Trace::Bool *node)
+{
+ m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::SInt *node)
+{
+ m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::UInt *node)
+{
+ m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::Float *node)
+{
+ m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::String *node)
+{
+ m_variant = QVariant(QString::fromStdString(node->value));
+}
+
+void VariantVisitor::visit(Trace::Enum *e)
+{
+ m_variant = QVariant(QString::fromStdString(e->sig->first));
+}
+
+void VariantVisitor::visit(Trace::Bitmask *bitmask)
+{
+ m_variant = QVariant::fromValue(ApiBitmask(bitmask));
+}
+
+void VariantVisitor::visit(Trace::Struct *str)
+{
+ m_variant = QVariant::fromValue(ApiStruct(str));
+}
+
+void VariantVisitor::visit(Trace::Array *array)
+{
+ m_variant = QVariant::fromValue(ApiArray(array));
+}
+
+void VariantVisitor::visit(Trace::Blob *blob)
+{
+ QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
+ m_variant = QVariant(barray);
+}
+
+void VariantVisitor::visit(Trace::Pointer *ptr)
+{
+ m_variant = QVariant::fromValue(ApiPointer(ptr->value));
+}
+
+ApiArray::ApiArray(const Trace::Array *arr)
+{
+ init(arr);
+}
+
+QString ApiArray::toString() const
+{
+ QString str;
+ str += QLatin1String("[");
+ for(int i = 0; i < m_array.count(); ++i) {
+ const QVariant &var = m_array[i];
+ str += apiVariantToString(var);
+ if (i < m_array.count() - 1)
+ str += QLatin1String(", ");
+ }
+ str += QLatin1String("]");
+
+ return str;
+}
+
+void ApiArray::init(const Trace::Array *arr)
+{
+ if (!arr)
+ return;
+
+ for (int i = 0; i < arr->values.size(); ++i) {
+ VariantVisitor vis;
+ arr->values[i]->visit(vis);
+
+ m_array.append(vis.variant());
+ }
+}
#include <QStringList>
#include <QVariant>
+#include "trace_model.hpp"
+
+
+class VariantVisitor : public Trace::Visitor
+{
+public:
+ virtual void visit(Trace::Null *);
+ virtual void visit(Trace::Bool *node);
+ virtual void visit(Trace::SInt *node);
+ virtual void visit(Trace::UInt *node);
+ virtual void visit(Trace::Float *node);
+ virtual void visit(Trace::String *node);
+ virtual void visit(Trace::Enum *e);
+ virtual void visit(Trace::Bitmask *bitmask);
+ virtual void visit(Trace::Struct *str);
+ virtual void visit(Trace::Array *array);
+ virtual void visit(Trace::Blob *blob);
+ virtual void visit(Trace::Pointer *ptr);
+
+ QVariant variant() const
+ {
+ return m_variant;
+ }
+private:
+ QVariant m_variant;
+};
+
+
+class ApiPointer
+{
+public:
+ ApiPointer(int val=0);
+
+ QString toString() const;
+private:
+ int m_value;
+};
+Q_DECLARE_METATYPE(ApiPointer);
+
+class ApiBitmask
+{
+public:
+ typedef QList<QPair<QString, unsigned long long> > Signature;
+
+ ApiBitmask(const Trace::Bitmask *bitmask = 0);
+
+ QString toString() const;
+
+private:
+ void init(const Trace::Bitmask *bitmask);
+private:
+ Signature m_sig;
+ unsigned long long m_value;
+};
+Q_DECLARE_METATYPE(ApiBitmask);
+
+class ApiStruct
+{
+public:
+ struct Signature {
+ QString name;
+ QStringList memberNames;
+ };
+
+ ApiStruct(const Trace::Struct *s = 0);
+
+ QString toString() const;
+
+private:
+ void init(const Trace::Struct *bitmask);
+private:
+ Signature m_sig;
+ QList<QVariant> m_members;
+};
+Q_DECLARE_METATYPE(ApiStruct);
+
+class ApiArray
+{
+public:
+ ApiArray(const Trace::Array *arr = 0);
+
+ QString toString() const;
+
+private:
+ void init(const Trace::Array *arr);
+private:
+ QList<QVariant> m_array;
+};
+Q_DECLARE_METATYPE(ApiArray);
+
+
+QString apiVariantToString(const QVariant &variant);
+
class ApiTraceCall
{
public:
--- /dev/null
+#include "apitracefilter.h"
+
+#include "apitracecall.h"
+
+ApiTraceFilter::ApiTraceFilter(QObject *parent )
+ : QSortFilterProxyModel()
+{
+}
+
+bool ApiTraceFilter::filterAcceptsRow(int sourceRow,
+ const QModelIndex &sourceParent) const
+{
+ QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
+ QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);
+ QModelIndex index2 = sourceModel()->index(sourceRow, 2, sourceParent);
+ QString function = sourceModel()->data(index0).toString();
+ QString arguments = sourceModel()->data(index1).toString();
+
+ //XXX make it configurable
+ if (function.contains(QLatin1String("glXGetProcAddress")))
+ return false;
+ if (function.contains(QLatin1String("wglGetProcAddress")))
+ return false;
+
+ if (function.contains(QLatin1String("glGetString")) &&
+ arguments.contains(QLatin1String("GL_EXTENSIONS")))
+ return false;
+
+ return true;
+}
+
+
+#include "apitracefilter.moc"
--- /dev/null
+#ifndef APITRACEFILTER_H
+#define APITRACEFILTER_H
+
+#include <QSortFilterProxyModel>
+
+//! [0]
+class ApiTraceFilter : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+public:
+ ApiTraceFilter(QObject *parent = 0);
+
+protected:
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+};
+
+#endif
#include "loaderthread.h"
#include "trace_parser.hpp"
+#include <QDebug>
#include <QVariant>
-class VariantVisitor : public Trace::Visitor
-{
-public:
- virtual void visit(Trace::Null *)
- {
- // Nothing
- }
- virtual void visit(Trace::Bool *node)
- {
- m_variant = QVariant(node->value);
- }
- virtual void visit(Trace::SInt *node)
- {
- m_variant = QVariant(node->value);
- }
- virtual void visit(Trace::UInt *node)
- {
- m_variant = QVariant(node->value);
- }
- virtual void visit(Trace::Float *node)
- {
- m_variant = QVariant(node->value);
- }
- virtual void visit(Trace::String *node)
- {
- m_variant = QVariant(QString::fromStdString(node->value));
- }
- virtual void visit(Trace::Enum *e)
- {
- m_variant = QVariant(QString::fromStdString(e->sig->first));
- }
- virtual void visit(Trace::Bitmask *bitmask)
- {
- //XXX we should probably convert it to QImage
- visit(static_cast<Trace::UInt *>(bitmask));
- }
- virtual void visit(Trace::Struct *str)
- {
- //XXX: need a custom QVariant type for this one
- QVariantList lst;
- for (int i = 0; i < str->members.size(); ++i) {
- VariantVisitor vst;
- str->members[i]->visit(vst);
- lst.append(vst.variant());
- }
- m_variant = QVariant(lst);
- }
- virtual void visit(Trace::Array *array)
- {
- QVariantList lst;
- for (int i = 0; i < array->values.size(); ++i) {
- VariantVisitor vst;
- array->values[i]->visit(vst);
- lst.append(vst.variant());
- }
- m_variant = QVariant(lst);
- }
- virtual void visit(Trace::Blob *blob)
- {
- QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
- m_variant = QVariant(barray);
- }
- virtual void visit(Trace::Pointer *ptr)
- {
- m_variant = QVariant(ptr->value);
- }
-
- QVariant variant() const
- {
- return m_variant;
- }
-private:
- QVariant m_variant;
-};
ApiTraceModel::ApiTraceModel(QObject *parent)
: QAbstractItemModel(parent)
{
m_loader = new LoaderThread();
+
connect(m_loader, SIGNAL(parsedCalls(const QList<Trace::Call*>&)),
SLOT(appendCalls(const QList<Trace::Call*>&)));
}
return QVariant();
switch (index.column()) {
- case 0:
- return item->name;
- case 1: {
+ case 0: {
QString str;
+ str += QString::number(index.row());
+ str += QLatin1String(") ");
+ str += item->name;
+ str += QLatin1String("(");
for (int i = 0; i < item->argNames.count(); ++i) {
str += item->argNames[i];
str += QString::fromLatin1(" = ");
- str += item->argValues[i].toString();
+ str += apiVariantToString(item->argValues[i]);
if (i < item->argNames.count() - 1)
str += QString::fromLatin1(", ");
}
+ str += QLatin1String(")");
+
+ if (item->returnValue.isValid()) {
+ str += QLatin1String(" = ");
+ str += apiVariantToString(item->returnValue);
+ }
return str;
}
- case 2:
- return item->returnValue.toString();
default:
return QVariant();
}
switch (section) {
case 0:
return tr("Function");
- case 1:
- return tr("Arguments");
- case 2:
- return tr("Return");
default:
//fall through
break;
int ApiTraceModel::columnCount(const QModelIndex &parent) const
{
- return parent.isValid() ? 0 : 3;
+ return parent.isValid() ? 0 : 1;
}
apiCall->argNames +=
QString::fromStdString(call->sig->arg_names[i]);
}
- VariantVisitor retVisitor;
if (call->ret) {
+ VariantVisitor retVisitor;
call->ret->visit(retVisitor);
apiCall->returnValue = retVisitor.variant();
}
call->args[i]->visit(argVisitor);
apiCall->argValues += argVisitor.variant();
}
+
m_calls.append(apiCall);
}
endInsertRows();
#include "mainwindow.h"
#include "apitracemodel.h"
+#include "apitracefilter.h"
#include <QAction>
#include <QDebug>
m_ui.setupUi(this);
m_model = new ApiTraceModel();
+ m_proxyModel = new ApiTraceFilter();
+ m_proxyModel->setSourceModel(m_model);
m_ui.callView->setModel(m_model);
for (int column = 0; column < m_model->columnCount(); ++column)
m_ui.callView->resizeColumnToContents(column);
#include <QtGui/QMainWindow>
class ApiTraceModel;
+class ApiTraceFilter;
class MainWindow : public QMainWindow
{
private:
Ui_MainWindow m_ui;
ApiTraceModel *m_model;
+ ApiTraceFilter *m_proxyModel;
};