2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-16 17:25:01 +01:00
|
|
|
**
|
2008-12-02 12:01:29 +01:00
|
|
|
** This file is part of Qt Creator
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-16 17:25:01 +01:00
|
|
|
**
|
2009-06-17 00:01:27 +10:00
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
2008-12-16 17:25:01 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Commercial Usage
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
** a written agreement between you and Nokia.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2008-12-16 17:25:01 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** If you are unsure which license is appropriate for your use, please
|
2009-06-17 00:01:27 +10:00
|
|
|
** contact the sales department at http://www.qtsoftware.com/contact.
|
2008-12-16 17:25:01 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
#include <qglobal.h>
|
|
|
|
|
2009-01-21 12:16:27 +01:00
|
|
|
#include <QtCore/QDateTime>
|
|
|
|
#include <QtCore/QDebug>
|
|
|
|
#include <QtCore/QDir>
|
|
|
|
#include <QtCore/QFile>
|
|
|
|
#include <QtCore/QFileInfo>
|
|
|
|
#include <QtCore/QHash>
|
|
|
|
#include <QtCore/QLinkedList>
|
|
|
|
#include <QtCore/QLocale>
|
|
|
|
#include <QtCore/QMap>
|
|
|
|
#include <QtCore/QMetaObject>
|
|
|
|
#include <QtCore/QMetaProperty>
|
2009-07-07 11:38:01 +02:00
|
|
|
#include <QtCore/QMetaEnum>
|
2009-01-21 12:16:27 +01:00
|
|
|
#include <QtCore/QModelIndex>
|
|
|
|
#include <QtCore/QObject>
|
|
|
|
#include <QtCore/QPointer>
|
|
|
|
#include <QtCore/QString>
|
|
|
|
#include <QtCore/QTextCodec>
|
|
|
|
#include <QtCore/QVector>
|
2009-07-06 17:36:50 +02:00
|
|
|
#include <QtCore/QTextStream>
|
|
|
|
#include <QtCore/QPoint>
|
|
|
|
#include <QtCore/QSize>
|
|
|
|
#include <QtCore/QRect>
|
|
|
|
#include <QtCore/QPointF>
|
|
|
|
#include <QtCore/QSizeF>
|
|
|
|
#include <QtCore/QRectF>
|
2009-06-25 15:00:57 +02:00
|
|
|
|
|
|
|
#if QT_VERSION >= 0x040500
|
|
|
|
#include <QtCore/QSharedPointer>
|
|
|
|
#include <QtCore/QSharedDataPointer>
|
2009-07-02 16:38:15 +02:00
|
|
|
#include <QtCore/QSharedData>
|
2009-04-28 10:58:55 +02:00
|
|
|
#include <QtCore/QWeakPointer>
|
2009-06-25 15:00:57 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-01-21 12:16:27 +01:00
|
|
|
int qtGhVersion = QT_VERSION;
|
|
|
|
|
2009-06-18 13:22:58 +02:00
|
|
|
#ifndef USE_QT_GUI
|
|
|
|
# ifdef QT_GUI_LIB
|
|
|
|
# define USE_QT_GUI 1
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_QT_GUI
|
2009-07-01 12:49:41 +02:00
|
|
|
# include <QtGui/QApplication>
|
2009-01-21 12:16:27 +01:00
|
|
|
# include <QtGui/QImage>
|
2009-07-01 12:49:41 +02:00
|
|
|
# include <QtGui/QPixmap>
|
|
|
|
# include <QtGui/QWidget>
|
2009-07-06 17:36:50 +02:00
|
|
|
# include <QtGui/QFont>
|
|
|
|
# include <QtGui/QColor>
|
|
|
|
# include <QtGui/QKeySequence>
|
|
|
|
# include <QtGui/QSizePolicy>
|
2009-01-21 12:16:27 +01:00
|
|
|
#endif
|
|
|
|
|
2009-04-29 14:15:09 +02:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
# include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
2009-01-21 12:16:27 +01:00
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
2009-03-11 13:31:38 +01:00
|
|
|
#include <set>
|
2009-01-21 12:16:27 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
\class QDumper
|
|
|
|
\brief Helper class for producing "nice" output in Qt Creator's debugger.
|
|
|
|
|
|
|
|
\internal
|
|
|
|
|
|
|
|
The whole "custom dumper" implementation is currently far less modular
|
|
|
|
than it could be. But as the code is still in a flux, making it nicer
|
|
|
|
from a pure archtectural point of view seems still be a waste of resources.
|
|
|
|
|
|
|
|
Some hints:
|
|
|
|
|
|
|
|
New dumpers for non-templated classes should be mentioned in
|
|
|
|
\c{qDumpObjectData440()} in the \c{protocolVersion == 1} branch.
|
|
|
|
|
|
|
|
Templated classes need extra support on the IDE level
|
|
|
|
(see plugins/debugger/gdbengine.cpp) and should not be mentiond in
|
|
|
|
\c{qDumpObjectData440()}.
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
In any case, dumper processesing should end up in
|
2009-05-05 18:49:35 +02:00
|
|
|
\c{handleProtocolVersion2and3()} and needs an entry in the big switch there.
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
Next step is to create a suitable \c{static void qDumpFoo(QDumper &d)}
|
2009-05-05 18:49:35 +02:00
|
|
|
function. At the bare minimum it should contain something like this:
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
\c{
|
|
|
|
const Foo &foo = *reinterpret_cast<const Foo *>(d.data);
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", ...);
|
|
|
|
d.putItem("type", "Foo");
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
'd.putItem(name, value)' roughly expands to:
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put((name)).put("=\"").put(value).put("\"";
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
Useful (i.e. understood by the IDE) names include:
|
|
|
|
|
|
|
|
\list
|
|
|
|
\o "name" shows up in the first column in the Locals&Watchers view.
|
|
|
|
\o "value" shows up in the second column.
|
|
|
|
\o "valueencoded" should be set to "1" if the value is base64 encoded.
|
|
|
|
Always base64-encode values that might use unprintable or otherwise
|
|
|
|
"confuse" the protocol (like spaces and quotes). [A-Za-z0-9] is "safe".
|
2009-06-26 10:50:58 +02:00
|
|
|
A value of "3" is used for base64-encoded UCS4, "2" denotes
|
2008-12-02 12:01:29 +01:00
|
|
|
base64-encoded UTF16.
|
|
|
|
\o "numchild" return the number of children in the view. Effectively, only
|
|
|
|
0 and != 0 will be used, so don't try too hard to get the number right.
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
If the current item has children, it might be queried to produce information
|
2009-05-05 18:49:35 +02:00
|
|
|
about these children. In this case the dumper should use something like this:
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
\c{
|
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
|
|
|
[...]
|
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#undef NS
|
|
|
|
#ifdef QT_NAMESPACE
|
|
|
|
# define STRINGIFY0(s) #s
|
|
|
|
# define STRINGIFY1(s) STRINGIFY0(s)
|
|
|
|
# define NS STRINGIFY1(QT_NAMESPACE) "::"
|
|
|
|
# define NSX "'" STRINGIFY1(QT_NAMESPACE) "::"
|
|
|
|
# define NSY "'"
|
|
|
|
#else
|
|
|
|
# define NS ""
|
|
|
|
# define NSX ""
|
|
|
|
# define NSY ""
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(QT_BEGIN_NAMESPACE)
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
#endif
|
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
struct Sender { QObject *sender; int signal; int ref; };
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
const char *stdStringTypeC = "std::basic_string<char,std::char_traits<char>,std::allocator<char> >";
|
|
|
|
const char *stdWideStringTypeUShortC = "std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >";
|
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
#if QT_VERSION < 0x040600
|
|
|
|
struct Connection
|
|
|
|
{
|
|
|
|
QObject *receiver;
|
|
|
|
int method;
|
|
|
|
uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
|
|
|
|
QBasicAtomicPointer<int> argumentTypes;
|
|
|
|
};
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
typedef QList<Connection> ConnectionList;
|
|
|
|
typedef QList<Sender> SenderList;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
const Connection &connectionAt(const ConnectionList &l, int i) { return l.at(i); }
|
|
|
|
const QObject *senderAt(const SenderList &l, int i) { return l.at(i).sender; }
|
|
|
|
int signalAt(const SenderList &l, int i) { return l.at(i).signal; }
|
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
#if QT_VERSION >= 0x040600
|
|
|
|
struct Connection
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
QObject *sender;
|
2009-05-13 16:11:25 +02:00
|
|
|
QObject *receiver;
|
|
|
|
int method;
|
|
|
|
uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
|
|
|
|
QBasicAtomicPointer<int> argumentTypes;
|
2009-06-25 15:00:57 +02:00
|
|
|
//senders linked list
|
|
|
|
//Connection *next;
|
|
|
|
//Connection **prev;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
typedef QList<Connection *> ConnectionList;
|
|
|
|
typedef ConnectionList SenderList;
|
|
|
|
|
|
|
|
const Connection &connectionAt(const ConnectionList &l, int i) { return *l.at(i); }
|
|
|
|
const QObject *senderAt(const SenderList &l, int i) { return l.at(i)->sender; }
|
|
|
|
// FIXME: 'method' is wrong
|
|
|
|
int signalAt(const SenderList &l, int i) { return l.at(i)->method; }
|
|
|
|
#endif
|
|
|
|
|
2009-06-25 15:00:57 +02:00
|
|
|
class ObjectPrivate : public QObjectData
|
2009-05-13 16:11:25 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-06-25 15:00:57 +02:00
|
|
|
ObjectPrivate() {}
|
|
|
|
virtual ~ObjectPrivate() {}
|
2009-05-13 16:11:25 +02:00
|
|
|
|
|
|
|
QList<QObject *> pendingChildInsertedEvents;
|
|
|
|
void *threadData;
|
|
|
|
void *currentSender;
|
|
|
|
void *currentChildBeingDeleted;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
QList<QPointer<QObject> > eventFilters;
|
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
void *extraData;
|
2008-12-02 12:01:29 +01:00
|
|
|
mutable quint32 connectedSignals;
|
|
|
|
|
|
|
|
QString objectName;
|
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
void *connectionLists;
|
|
|
|
SenderList senders;
|
2008-12-02 12:01:29 +01:00
|
|
|
int *deleteWatch;
|
|
|
|
};
|
|
|
|
|
2009-05-13 16:11:25 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#if defined(QT_BEGIN_NAMESPACE)
|
|
|
|
QT_END_NAMESPACE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2009-04-15 16:48:06 +02:00
|
|
|
// This can be mangled typenames of nested templates, each char-by-char
|
|
|
|
// comma-separated integer list...
|
|
|
|
// The output buffer.
|
2009-06-25 15:00:57 +02:00
|
|
|
#ifdef MACROSDEBUG
|
|
|
|
Q_DECL_EXPORT char xDumpInBuffer[10000];
|
|
|
|
Q_DECL_EXPORT char xDumpOutBuffer[1000000];
|
|
|
|
#define inBuffer xDumpInBuffer
|
|
|
|
#define outBuffer xDumpOutBuffer
|
|
|
|
#else
|
|
|
|
Q_DECL_EXPORT char qDumpInBuffer[10000];
|
|
|
|
Q_DECL_EXPORT char qDumpOutBuffer[1000000];
|
|
|
|
#define inBuffer qDumpInBuffer
|
|
|
|
#define outBuffer qDumpOutBuffer
|
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2009-05-05 18:52:57 +02:00
|
|
|
static QByteArray strPtrConst = "* const";
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
static bool isPointerType(const QByteArray &type)
|
|
|
|
{
|
2009-05-05 18:52:57 +02:00
|
|
|
return type.endsWith('*') || type.endsWith(strPtrConst);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-05-05 18:52:57 +02:00
|
|
|
static QByteArray stripPointerType(const QByteArray &_type)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-05-05 18:52:57 +02:00
|
|
|
QByteArray type = _type;
|
|
|
|
if (type.endsWith('*'))
|
2008-12-02 12:01:29 +01:00
|
|
|
type.chop(1);
|
2009-05-05 18:52:57 +02:00
|
|
|
if (type.endsWith(strPtrConst))
|
2008-12-02 12:01:29 +01:00
|
|
|
type.chop(7);
|
|
|
|
if (type.endsWith(' '))
|
|
|
|
type.chop(1);
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is used to abort evaluation of custom data dumpers in a "coordinated"
|
2009-04-29 14:15:09 +02:00
|
|
|
// way. Abortion will happen at the latest when we try to access a non-initialized
|
2008-12-02 12:01:29 +01:00
|
|
|
// non-trivial object, so there is no way to prevent this from occuring at all
|
2009-04-29 14:15:09 +02:00
|
|
|
// conceptionally. Ideally, if there is API to check memory access, it should
|
|
|
|
// be used to terminate nicely, especially with CDB.
|
|
|
|
// 1) Gdb will catch SIGSEGV and return to the calling frame.
|
|
|
|
// This is just fine provided we only _read_ memory in the custom handlers
|
|
|
|
// below.
|
|
|
|
// 2) For MSVC/CDB, exceptions must be handled in the dumper, which is
|
|
|
|
// achieved using __try/__except. The exception will be reported in the
|
|
|
|
// debugger, which will then execute a 'gN' command, passing handling back
|
|
|
|
// to the __except clause.
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
volatile int qProvokeSegFaultHelper;
|
|
|
|
|
|
|
|
static const void *addOffset(const void *p, int offset)
|
|
|
|
{
|
|
|
|
return offset + reinterpret_cast<const char *>(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const void *skipvtable(const void *p)
|
|
|
|
{
|
2009-03-12 11:49:04 +01:00
|
|
|
return sizeof(void *) + reinterpret_cast<const char *>(p);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static const void *deref(const void *p)
|
|
|
|
{
|
|
|
|
return *reinterpret_cast<const char* const*>(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const void *dfunc(const void *p)
|
|
|
|
{
|
|
|
|
return deref(skipvtable(p));
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isEqual(const char *s, const char *t)
|
|
|
|
{
|
|
|
|
return qstrcmp(s, t) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool startsWith(const char *s, const char *t)
|
|
|
|
{
|
2009-05-05 18:52:57 +02:00
|
|
|
while (char c = *t++)
|
|
|
|
if (c != *s++)
|
|
|
|
return false;
|
|
|
|
return true;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-04-29 14:15:09 +02:00
|
|
|
// Check memory for read access and provoke segfault if nothing else helps.
|
|
|
|
// On Windows, try to be less crash-prone by checking memory using WinAPI
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
2009-05-06 09:22:05 +02:00
|
|
|
# define qCheckAccess(d) do { if (IsBadReadPtr(d, 1)) return; qProvokeSegFaultHelper = *(char*)d; } while (0)
|
|
|
|
# define qCheckPointer(d) do { if (d && IsBadReadPtr(d, 1)) return; if (d) qProvokeSegFaultHelper = *(char*)d; } while (0)
|
2009-04-29 14:15:09 +02:00
|
|
|
#else
|
|
|
|
# define qCheckAccess(d) do { qProvokeSegFaultHelper = *(char*)d; } while (0)
|
|
|
|
# define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0)
|
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-05 18:52:57 +02:00
|
|
|
#ifdef QT_NAMESPACE
|
2008-12-02 12:01:29 +01:00
|
|
|
const char *stripNamespace(const char *type)
|
|
|
|
{
|
2009-05-05 18:52:57 +02:00
|
|
|
static const size_t nslen = strlen(NS);
|
2008-12-02 12:01:29 +01:00
|
|
|
return startsWith(type, NS) ? type + nslen : type;
|
|
|
|
}
|
2009-05-05 18:52:57 +02:00
|
|
|
#else
|
|
|
|
inline const char *stripNamespace(const char *type)
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
static bool isSimpleType(const char *type)
|
|
|
|
{
|
|
|
|
switch (type[0]) {
|
|
|
|
case 'c':
|
|
|
|
return isEqual(type, "char");
|
|
|
|
case 'd':
|
|
|
|
return isEqual(type, "double");
|
|
|
|
case 'f':
|
|
|
|
return isEqual(type, "float");
|
|
|
|
case 'i':
|
|
|
|
return isEqual(type, "int");
|
|
|
|
case 'l':
|
|
|
|
return isEqual(type, "long") || startsWith(type, "long ");
|
|
|
|
case 's':
|
2009-06-24 14:35:53 +02:00
|
|
|
return isEqual(type, "short") || startsWith(type, "short ")
|
|
|
|
|| isEqual(type, "signed") || startsWith(type, "signed ");
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'u':
|
|
|
|
return isEqual(type, "unsigned") || startsWith(type, "unsigned ");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-01-28 16:55:09 +01:00
|
|
|
static bool isStringType(const char *type)
|
|
|
|
{
|
|
|
|
return isEqual(type, NS"QString")
|
|
|
|
|| isEqual(type, NS"QByteArray")
|
|
|
|
|| isEqual(type, "std::string")
|
|
|
|
|| isEqual(type, "std::wstring")
|
|
|
|
|| isEqual(type, "wstring");
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
static bool isMovableType(const char *type)
|
|
|
|
{
|
|
|
|
if (isPointerType(type))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (isSimpleType(type))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
type = stripNamespace(type);
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
switch (type[1]) {
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'B':
|
|
|
|
return isEqual(type, "QBrush")
|
|
|
|
|| isEqual(type, "QBitArray")
|
|
|
|
|| isEqual(type, "QByteArray") ;
|
|
|
|
case 'C':
|
2009-06-24 14:35:53 +02:00
|
|
|
return isEqual(type, "QCustomTypeInfo")
|
|
|
|
|| isEqual(type, "QChar");
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'D':
|
|
|
|
return isEqual(type, "QDate")
|
|
|
|
|| isEqual(type, "QDateTime");
|
|
|
|
case 'F':
|
|
|
|
return isEqual(type, "QFileInfo")
|
|
|
|
|| isEqual(type, "QFixed")
|
|
|
|
|| isEqual(type, "QFixedPoint")
|
|
|
|
|| isEqual(type, "QFixedSize");
|
|
|
|
case 'H':
|
|
|
|
return isEqual(type, "QHashDummyValue");
|
|
|
|
case 'I':
|
|
|
|
return isEqual(type, "QIcon")
|
|
|
|
|| isEqual(type, "QImage");
|
|
|
|
case 'L':
|
|
|
|
return isEqual(type, "QLine")
|
|
|
|
|| isEqual(type, "QLineF")
|
2009-06-24 14:35:53 +02:00
|
|
|
|| isEqual(type, "QLatin1Char")
|
2008-12-02 12:01:29 +01:00
|
|
|
|| isEqual(type, "QLocal");
|
|
|
|
case 'M':
|
|
|
|
return isEqual(type, "QMatrix")
|
|
|
|
|| isEqual(type, "QModelIndex");
|
|
|
|
case 'P':
|
|
|
|
return isEqual(type, "QPoint")
|
|
|
|
|| isEqual(type, "QPointF")
|
|
|
|
|| isEqual(type, "QPen")
|
|
|
|
|| isEqual(type, "QPersistentModelIndex");
|
|
|
|
case 'R':
|
|
|
|
return isEqual(type, "QResourceRoot")
|
|
|
|
|| isEqual(type, "QRect")
|
|
|
|
|| isEqual(type, "QRectF")
|
|
|
|
|| isEqual(type, "QRegExp");
|
|
|
|
case 'S':
|
|
|
|
return isEqual(type, "QSize")
|
|
|
|
|| isEqual(type, "QSizeF")
|
|
|
|
|| isEqual(type, "QString");
|
|
|
|
case 'T':
|
|
|
|
return isEqual(type, "QTime")
|
|
|
|
|| isEqual(type, "QTextBlock");
|
|
|
|
case 'U':
|
|
|
|
return isEqual(type, "QUrl");
|
|
|
|
case 'V':
|
|
|
|
return isEqual(type, "QVariant");
|
|
|
|
case 'X':
|
|
|
|
return isEqual(type, "QXmlStreamAttribute")
|
|
|
|
|| isEqual(type, "QXmlStreamNamespaceDeclaration")
|
|
|
|
|| isEqual(type, "QXmlStreamNotationDeclaration")
|
|
|
|
|| isEqual(type, "QXmlStreamEntityDeclaration");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct QDumper
|
|
|
|
{
|
|
|
|
explicit QDumper();
|
|
|
|
~QDumper();
|
2009-06-26 10:50:58 +02:00
|
|
|
|
2009-07-06 17:36:50 +02:00
|
|
|
// direct write to the output
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &put(long c);
|
|
|
|
QDumper &put(int i);
|
|
|
|
QDumper &put(double d);
|
|
|
|
QDumper &put(float d);
|
|
|
|
QDumper &put(unsigned long c);
|
|
|
|
QDumper &put(unsigned int i);
|
|
|
|
QDumper &put(const void *p);
|
|
|
|
QDumper &put(qulonglong c);
|
2009-07-06 17:36:50 +02:00
|
|
|
QDumper &put(long long c);
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &put(const char *str);
|
|
|
|
QDumper &put(const QByteArray &ba);
|
|
|
|
QDumper &put(const QString &str);
|
|
|
|
QDumper &put(char c);
|
|
|
|
|
|
|
|
// convienience functions for writing key="value" pairs:
|
2009-06-26 10:50:58 +02:00
|
|
|
template <class Value>
|
2009-06-26 11:32:51 +02:00
|
|
|
void putItem(const char *name, const Value &value)
|
|
|
|
{
|
|
|
|
putCommaIfNeeded();
|
|
|
|
put(name).put('=').put('"').put(value).put('"');
|
|
|
|
}
|
|
|
|
|
|
|
|
// convienience functions for writing typical properties.
|
|
|
|
// roughly equivalent to
|
|
|
|
// beginHash();
|
|
|
|
// putItem("name", name);
|
|
|
|
// putItem("value", value);
|
|
|
|
// putItem("type", NS"QString");
|
|
|
|
// putItem("numchild", "0");
|
|
|
|
// putItem("valueencoded", "2");
|
|
|
|
// endHash();
|
|
|
|
void putHash(const char *name, const QString &value);
|
|
|
|
void putHash(const char *name, const QByteArray &value);
|
|
|
|
void putHash(const char *name, int value);
|
|
|
|
void putHash(const char *name, long value);
|
|
|
|
void putHash(const char *name, bool value);
|
|
|
|
void putHash(const char *name, QChar value);
|
|
|
|
|
|
|
|
void beginHash(); // start of data hash output
|
|
|
|
void endHash(); // start of data hash output
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
void beginChildren(const char *mainInnerType = 0); // start of children list
|
2009-06-26 11:32:51 +02:00
|
|
|
void endChildren(); // end of children list
|
|
|
|
|
|
|
|
void beginItem(const char *name); // start of named item, ready to accept value
|
|
|
|
void endItem(); // end of named item, used after value output is complete
|
2009-06-26 10:50:58 +02:00
|
|
|
|
|
|
|
// convienience for putting "<n items>"
|
|
|
|
void putItemCount(const char *name, int count);
|
2009-06-26 11:32:51 +02:00
|
|
|
void putCommaIfNeeded();
|
|
|
|
// convienience function for writing the last item of an abbreviated list
|
2008-12-10 16:31:50 +01:00
|
|
|
void putEllipsis();
|
2008-12-02 12:01:29 +01:00
|
|
|
void disarm();
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
void putBase64Encoded(const char *buf, int n);
|
|
|
|
void checkFill();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
// the dumper arguments
|
|
|
|
int protocolVersion; // dumper protocol version
|
|
|
|
int token; // some token to show on success
|
|
|
|
const char *outertype; // object type
|
|
|
|
const char *iname; // object name used for display
|
|
|
|
const char *exp; // object expression
|
|
|
|
const char *innertype; // 'inner type' for class templates
|
|
|
|
const void *data; // pointer to raw data
|
|
|
|
bool dumpChildren; // do we want to see children?
|
|
|
|
|
|
|
|
// handling of nested templates
|
|
|
|
void setupTemplateParameters();
|
|
|
|
enum { maxTemplateParameters = 10 };
|
|
|
|
const char *templateParameters[maxTemplateParameters + 1];
|
|
|
|
|
|
|
|
// internal state
|
2009-06-26 11:32:51 +02:00
|
|
|
int extraInt[4];
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
bool success; // are we finished?
|
2009-01-21 11:57:14 +01:00
|
|
|
bool full;
|
2008-12-02 12:01:29 +01:00
|
|
|
int pos;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
QDumper::QDumper()
|
|
|
|
{
|
|
|
|
success = false;
|
2009-01-21 11:57:14 +01:00
|
|
|
full = false;
|
2009-06-26 10:50:58 +02:00
|
|
|
outBuffer[0] = 'f'; // marks output as 'wrong'
|
2009-01-21 11:57:14 +01:00
|
|
|
pos = 1;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QDumper::~QDumper()
|
|
|
|
{
|
2009-06-25 15:00:57 +02:00
|
|
|
outBuffer[pos++] = '\0';
|
2009-01-21 11:57:14 +01:00
|
|
|
if (success)
|
2009-06-25 15:00:57 +02:00
|
|
|
outBuffer[0] = (full ? '+' : 't');
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::setupTemplateParameters()
|
|
|
|
{
|
|
|
|
char *s = const_cast<char *>(innertype);
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
int templateParametersCount = 1;
|
2008-12-02 12:01:29 +01:00
|
|
|
templateParameters[0] = s;
|
|
|
|
for (int i = 1; i != maxTemplateParameters + 1; ++i)
|
|
|
|
templateParameters[i] = 0;
|
|
|
|
|
|
|
|
while (*s) {
|
|
|
|
while (*s && *s != '@')
|
|
|
|
++s;
|
|
|
|
if (*s) {
|
|
|
|
*s = '\0';
|
|
|
|
++s;
|
|
|
|
templateParameters[templateParametersCount++] = s;
|
|
|
|
}
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
while (templateParametersCount < maxTemplateParameters)
|
|
|
|
templateParameters[templateParametersCount++] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDumper &QDumper::put(char c)
|
|
|
|
{
|
|
|
|
checkFill();
|
|
|
|
if (!full)
|
|
|
|
outBuffer[pos++] = c;
|
|
|
|
return *this;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(unsigned long long c)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
checkFill();
|
2009-06-25 15:00:57 +02:00
|
|
|
pos += sprintf(outBuffer + pos, "%llu", c);
|
2008-12-02 12:01:29 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-07-06 17:36:50 +02:00
|
|
|
QDumper &QDumper::put(long long c)
|
|
|
|
{
|
|
|
|
checkFill();
|
|
|
|
pos += sprintf(outBuffer + pos, "%lld", c);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(unsigned long c)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
checkFill();
|
2009-06-25 15:00:57 +02:00
|
|
|
pos += sprintf(outBuffer + pos, "%lu", c);
|
2008-12-02 12:01:29 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(float d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
checkFill();
|
2009-06-25 15:00:57 +02:00
|
|
|
pos += sprintf(outBuffer + pos, "%f", d);
|
2008-12-02 12:01:29 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(double d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
checkFill();
|
2009-06-25 15:00:57 +02:00
|
|
|
pos += sprintf(outBuffer + pos, "%f", d);
|
2008-12-02 12:01:29 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(unsigned int i)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
checkFill();
|
2009-06-25 15:00:57 +02:00
|
|
|
pos += sprintf(outBuffer + pos, "%u", i);
|
2008-12-02 12:01:29 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(long c)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
checkFill();
|
2009-06-25 15:00:57 +02:00
|
|
|
pos += sprintf(outBuffer + pos, "%ld", c);
|
2008-12-02 12:01:29 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(int i)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
checkFill();
|
2009-06-25 15:00:57 +02:00
|
|
|
pos += sprintf(outBuffer + pos, "%d", i);
|
2008-12-02 12:01:29 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(const void *p)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
static char buf[100];
|
|
|
|
if (p) {
|
|
|
|
sprintf(buf, "%p", p);
|
|
|
|
// we get a '0x' prefix only on some implementations.
|
|
|
|
// if it isn't there, write it out manually.
|
|
|
|
if (buf[1] != 'x') {
|
|
|
|
put('0');
|
|
|
|
put('x');
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
put(buf);
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-06-26 11:32:51 +02:00
|
|
|
put("<null>");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(const char *str)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-06-26 11:32:51 +02:00
|
|
|
if (!str)
|
|
|
|
return put("<null>");
|
|
|
|
while (*str)
|
|
|
|
put(*(str++));
|
|
|
|
return *this;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(const QByteArray &ba)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-06-26 11:32:51 +02:00
|
|
|
putBase64Encoded(ba.constData(), ba.size());
|
|
|
|
return *this;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
QDumper &QDumper::put(const QString &str)
|
|
|
|
{
|
|
|
|
putBase64Encoded((const char *)str.constData(), 2 * str.size());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::checkFill()
|
|
|
|
{
|
|
|
|
if (pos >= int(sizeof(outBuffer)) - 100)
|
|
|
|
full = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::putCommaIfNeeded()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
if (pos == 0)
|
|
|
|
return;
|
2009-06-25 15:00:57 +02:00
|
|
|
char c = outBuffer[pos - 1];
|
2009-01-27 17:15:51 +01:00
|
|
|
if (c == '}' || c == '"' || c == ']')
|
2008-12-02 12:01:29 +01:00
|
|
|
put(',');
|
|
|
|
}
|
|
|
|
|
2009-01-28 16:55:09 +01:00
|
|
|
void QDumper::putBase64Encoded(const char *buf, int n)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
|
|
|
|
"ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
|
|
|
|
const char padchar = '=';
|
|
|
|
int padlen = 0;
|
|
|
|
|
|
|
|
//int tmpsize = ((n * 4) / 3) + 3;
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
while (i < n) {
|
|
|
|
int chunk = 0;
|
|
|
|
chunk |= int(uchar(buf[i++])) << 16;
|
|
|
|
if (i == n) {
|
|
|
|
padlen = 2;
|
|
|
|
} else {
|
|
|
|
chunk |= int(uchar(buf[i++])) << 8;
|
|
|
|
if (i == n)
|
|
|
|
padlen = 1;
|
|
|
|
else
|
|
|
|
chunk |= int(uchar(buf[i++]));
|
|
|
|
}
|
|
|
|
|
|
|
|
int j = (chunk & 0x00fc0000) >> 18;
|
|
|
|
int k = (chunk & 0x0003f000) >> 12;
|
|
|
|
int l = (chunk & 0x00000fc0) >> 6;
|
|
|
|
int m = (chunk & 0x0000003f);
|
|
|
|
put(alphabet[j]);
|
|
|
|
put(alphabet[k]);
|
|
|
|
put(padlen > 1 ? padchar : alphabet[l]);
|
|
|
|
put(padlen > 0 ? padchar : alphabet[m]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::disarm()
|
|
|
|
{
|
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::beginHash()
|
|
|
|
{
|
2009-06-26 11:32:51 +02:00
|
|
|
putCommaIfNeeded();
|
2008-12-02 12:01:29 +01:00
|
|
|
put('{');
|
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::endHash()
|
|
|
|
{
|
|
|
|
put('}');
|
|
|
|
}
|
|
|
|
|
2008-12-10 16:31:50 +01:00
|
|
|
void QDumper::putEllipsis()
|
|
|
|
{
|
2009-06-26 11:32:51 +02:00
|
|
|
putCommaIfNeeded();
|
|
|
|
put("{name=\"<incomplete>\",value=\"\",type=\"").put(innertype).put("\"}");
|
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::putItemCount(const char *name, int count)
|
|
|
|
{
|
|
|
|
putCommaIfNeeded();
|
|
|
|
put(name).put("=\"<").put(count).put(" items>\"");
|
2008-12-10 16:31:50 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
//
|
|
|
|
// Some helpers to keep the dumper code short
|
|
|
|
//
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
void QDumper::beginItem(const char *name)
|
|
|
|
{
|
2009-06-26 11:32:51 +02:00
|
|
|
putCommaIfNeeded();
|
|
|
|
put(name).put('=').put('"');
|
2009-06-26 10:50:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void QDumper::endItem()
|
|
|
|
{
|
2009-06-26 11:32:51 +02:00
|
|
|
put('"');
|
2009-06-26 10:50:58 +02:00
|
|
|
}
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
void QDumper::beginChildren(const char *mainInnerType)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
2009-07-10 11:08:26 +02:00
|
|
|
if (mainInnerType) {
|
|
|
|
putItem("childtype", mainInnerType);
|
|
|
|
if (isSimpleType(mainInnerType) || isStringType(mainInnerType))
|
|
|
|
putItem("childnumchild", "0");
|
|
|
|
else if (isPointerType(mainInnerType))
|
|
|
|
putItem("childnumchild", "1");
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
putCommaIfNeeded();
|
|
|
|
put("children=[");
|
2009-06-26 10:50:58 +02:00
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
void QDumper::endChildren()
|
|
|
|
{
|
|
|
|
put(']');
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
// simple string property
|
2009-06-26 11:32:51 +02:00
|
|
|
void QDumper::putHash(const char *name, const QString &value)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
|
|
|
beginHash();
|
|
|
|
putItem("name", name);
|
|
|
|
putItem("value", value);
|
|
|
|
putItem("type", NS"QString");
|
|
|
|
putItem("numchild", "0");
|
|
|
|
putItem("valueencoded", "2");
|
|
|
|
endHash();
|
|
|
|
}
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
void QDumper::putHash(const char *name, const QByteArray &value)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
|
|
|
beginHash();
|
|
|
|
putItem("name", name);
|
|
|
|
putItem("value", value);
|
|
|
|
putItem("type", NS"QByteArray");
|
|
|
|
putItem("numchild", "0");
|
|
|
|
putItem("valueencoded", "1");
|
|
|
|
endHash();
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
// simple integer property
|
2009-06-26 11:32:51 +02:00
|
|
|
void QDumper::putHash(const char *name, int value)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
|
|
|
beginHash();
|
|
|
|
putItem("name", name);
|
|
|
|
putItem("value", value);
|
|
|
|
putItem("type", "int");
|
|
|
|
putItem("numchild", "0");
|
|
|
|
endHash();
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
|
|
|
|
void QDumper::putHash(const char *name, long value)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
|
|
|
beginHash();
|
|
|
|
putItem("name", name);
|
|
|
|
putItem("value", value);
|
|
|
|
putItem("type", "long");
|
|
|
|
putItem("numchild", "0");
|
|
|
|
endHash();
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
// simple boolean property
|
2009-06-26 11:32:51 +02:00
|
|
|
void QDumper::putHash(const char *name, bool value)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
|
|
|
beginHash();
|
|
|
|
putItem("name", name);
|
|
|
|
putItem("value", (value ? "true" : "false"));
|
|
|
|
putItem("type", "bool");
|
|
|
|
putItem("numchild", "0");
|
|
|
|
endHash();
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
// a single QChar
|
2009-06-26 11:32:51 +02:00
|
|
|
void QDumper::putHash(const char *name, QChar value)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
|
|
|
beginHash();
|
|
|
|
putItem("name", name);
|
|
|
|
putItem("value", QString(QLatin1String("'%1' (%2, 0x%3)"))
|
|
|
|
.arg(value).arg(value.unicode()).arg(value.unicode(), 0, 16));
|
|
|
|
putItem("valueencoded", "2");
|
|
|
|
putItem("type", NS"QChar");
|
|
|
|
putItem("numchild", "0");
|
|
|
|
endHash();
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-04-29 14:15:09 +02:00
|
|
|
#define DUMPUNKNOWN_MESSAGE "<internal error>"
|
|
|
|
static void qDumpUnknown(QDumper &d, const char *why = 0)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-06-26 10:50:58 +02:00
|
|
|
//d.putItem("iname", d.iname);
|
|
|
|
//d.putItem("addr", d.data);
|
2009-04-29 14:15:09 +02:00
|
|
|
if (!why)
|
|
|
|
why = DUMPUNKNOWN_MESSAGE;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", why);
|
|
|
|
d.putItem("type", d.outertype);
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
static void qDumpStdStringValue(QDumper &d, const std::string &str)
|
2009-07-03 13:56:27 +02:00
|
|
|
{
|
|
|
|
d.beginItem("value");
|
|
|
|
d.putBase64Encoded(str.c_str(), str.size());
|
|
|
|
d.endItem();
|
|
|
|
d.putItem("valueencoded", "1");
|
|
|
|
d.putItem("type", "std::string");
|
|
|
|
d.putItem("numchild", "0");
|
|
|
|
}
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
static void qDumpStdWStringValue(QDumper &d, const std::wstring &str)
|
2009-07-03 13:56:27 +02:00
|
|
|
{
|
|
|
|
d.beginItem("value");
|
|
|
|
d.putBase64Encoded((const char *)str.c_str(), str.size() * sizeof(wchar_t));
|
|
|
|
d.endItem();
|
|
|
|
d.putItem("valueencoded", (sizeof(wchar_t) == 2 ? "2" : "3"));
|
|
|
|
d.putItem("type", "std::wstring");
|
|
|
|
d.putItem("numchild", "0");
|
|
|
|
}
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
// Called by templates, so, not static.
|
2009-07-08 17:27:45 +02:00
|
|
|
static void qDumpInnerQCharValue(QDumper &d, QChar c, const char *field)
|
|
|
|
{
|
|
|
|
char buf[30];
|
|
|
|
sprintf(buf, "'?', ucs=%d", c.unicode());
|
|
|
|
if (c.isPrint() && c.unicode() < 127)
|
|
|
|
buf[1] = char(c.unicode());
|
|
|
|
d.putCommaIfNeeded();
|
|
|
|
d.putItem(field, buf);
|
|
|
|
d.putItem("numchild", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpInnerCharValue(QDumper &d, char c, const char *field)
|
|
|
|
{
|
|
|
|
char buf[30];
|
|
|
|
sprintf(buf, "'?', ascii=%d", c);
|
|
|
|
if (QChar(c).isPrint() && c < 127)
|
|
|
|
buf[1] = c;
|
|
|
|
d.putCommaIfNeeded();
|
|
|
|
d.putItem(field, buf);
|
|
|
|
d.putItem("numchild", 0);
|
|
|
|
}
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
void qDumpInnerValueHelper(QDumper &d, const char *type, const void *addr,
|
2009-01-28 15:06:05 +01:00
|
|
|
const char *field = "value")
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
type = stripNamespace(type);
|
|
|
|
switch (type[1]) {
|
2009-07-08 17:27:45 +02:00
|
|
|
case 'h':
|
2009-07-10 11:08:26 +02:00
|
|
|
if (isEqual(type, "char"))
|
2009-07-08 17:27:45 +02:00
|
|
|
qDumpInnerCharValue(d, *(char *)addr, field);
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'l':
|
|
|
|
if (isEqual(type, "float"))
|
2009-07-10 11:08:26 +02:00
|
|
|
d.putItem(field, *(float*)addr);
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'n':
|
2009-07-10 11:08:26 +02:00
|
|
|
if (isEqual(type, "int"))
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(int*)addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
else if (isEqual(type, "unsigned") || isEqual(type, "unsigned int"))
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(unsigned int*)addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
else if (isEqual(type, "unsigned char"))
|
2009-07-08 17:27:45 +02:00
|
|
|
qDumpInnerCharValue(d, *(char *)addr, field);
|
2009-07-10 11:08:26 +02:00
|
|
|
else if (isEqual(type, "unsigned long"))
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(unsigned long*)addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
else if (isEqual(type, "unsigned long long"))
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(qulonglong*)addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'o':
|
2009-07-06 17:36:50 +02:00
|
|
|
if (isEqual(type, "bool")) {
|
2008-12-02 12:01:29 +01:00
|
|
|
switch (*(bool*)addr) {
|
2009-07-06 17:36:50 +02:00
|
|
|
case 0: d.putItem(field, "false"); break;
|
|
|
|
case 1: d.putItem(field, "true"); break;
|
|
|
|
default: d.putItem(field, *(bool*)addr); break;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
} else if (isEqual(type, "double"))
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(double*)addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
else if (isEqual(type, "long"))
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(long*)addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
else if (isEqual(type, "long long"))
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(qulonglong*)addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'B':
|
|
|
|
if (isEqual(type, "QByteArray")) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.putCommaIfNeeded();
|
|
|
|
d.put(field).put("encoded=\"1\",");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(QByteArray*)addr);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2009-06-24 14:35:53 +02:00
|
|
|
case 'C':
|
2009-07-10 11:08:26 +02:00
|
|
|
if (isEqual(type, "QChar"))
|
2009-07-08 17:27:45 +02:00
|
|
|
qDumpInnerQCharValue(d, *(QChar*)addr, field);
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'L':
|
|
|
|
if (startsWith(type, "QList<")) {
|
|
|
|
const QListData *ldata = reinterpret_cast<const QListData*>(addr);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", ldata->size());
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", ldata->size());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'O':
|
|
|
|
if (isEqual(type, "QObject *")) {
|
|
|
|
if (addr) {
|
|
|
|
const QObject *ob = reinterpret_cast<const QObject *>(addr);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", ob);
|
|
|
|
d.putItem("value", ob->objectName());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QObject");
|
|
|
|
d.putItem("displayedtype", ob->metaObject()->className());
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("numchild", 1);
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "0x0");
|
|
|
|
d.putItem("type", NS"QObject *");
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("numchild", 0);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'S':
|
|
|
|
if (isEqual(type, "QString")) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.putCommaIfNeeded();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem(field, *(QString*)addr);
|
2009-07-08 17:27:45 +02:00
|
|
|
d.put(',').put(field).put("encoded=\"2\"");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2009-07-03 13:56:27 +02:00
|
|
|
case 't':
|
|
|
|
if (isEqual(type, "std::string")
|
2009-07-07 16:00:45 +02:00
|
|
|
|| isEqual(type, stdStringTypeC)) {
|
2009-07-03 13:56:27 +02:00
|
|
|
d.putCommaIfNeeded();
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpStdStringValue(d, *reinterpret_cast<const std::string*>(addr));
|
|
|
|
} else if (isEqual(type, "std::wstring")
|
2009-07-07 16:00:45 +02:00
|
|
|
|| isEqual(type, stdWideStringTypeUShortC)) {
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpStdWStringValue(d, *reinterpret_cast<const std::wstring*>(addr));
|
2009-07-03 13:56:27 +02:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
default:
|
2009-07-06 17:36:50 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
static void qDumpInnerValue(QDumper &d, const char *type, const void *addr)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", addr);
|
|
|
|
d.putItem("type", type);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
if (!type[0])
|
2009-07-10 11:08:26 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-07-06 17:36:50 +02:00
|
|
|
return qDumpInnerValueHelper(d, type, addr);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
static void qDumpInnerValueOrPointer(QDumper &d,
|
2008-12-10 16:31:50 +01:00
|
|
|
const char *type, const char *strippedtype, const void *addr)
|
|
|
|
{
|
|
|
|
if (strippedtype) {
|
|
|
|
if (deref(addr)) {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", deref(addr));
|
|
|
|
d.putItem("saddr", deref(addr));
|
|
|
|
d.putItem("type", strippedtype);
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueHelper(d, strippedtype, deref(addr));
|
|
|
|
} else {
|
|
|
|
d.putItem("addr", addr);
|
|
|
|
d.putItem("type", strippedtype);
|
|
|
|
d.putItem("value", "<null>");
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-10 16:31:50 +01:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
} else {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", addr);
|
2009-07-10 11:08:26 +02:00
|
|
|
d.putItem("type", type);
|
|
|
|
qDumpInnerValueHelper(d, type, addr);
|
2008-12-10 16:31:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2009-06-03 12:46:55 +02:00
|
|
|
struct ModelIndex { int r; int c; void *p; void *m; };
|
|
|
|
|
|
|
|
static void qDumpQAbstractItem(QDumper &d)
|
|
|
|
{
|
|
|
|
ModelIndex mm;
|
|
|
|
mm.r = mm.c = 0;
|
|
|
|
mm.p = mm.m = 0;
|
|
|
|
sscanf(d.templateParameters[0], "%d,%d,%p,%p", &mm.r, &mm.c, &mm.p, &mm.m);
|
|
|
|
const QModelIndex &mi(*reinterpret_cast<QModelIndex *>(&mm));
|
|
|
|
const QAbstractItemModel *m = mi.model();
|
|
|
|
const int rowCount = m->rowCount(mi);
|
|
|
|
if (rowCount < 0)
|
|
|
|
return;
|
|
|
|
const int columnCount = m->columnCount(mi);
|
|
|
|
if (columnCount < 0)
|
|
|
|
return;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QAbstractItem");
|
|
|
|
d.beginItem("addr");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put('$').put(mm.r).put(',').put(mm.c).put(',').put(mm.p).put(',').put(mm.m);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2009-06-26 11:32:51 +02:00
|
|
|
//d.putItem("value", "(").put(rowCount).put(",").put(columnCount).put(")");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", m->data(mi, Qt::DisplayRole).toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("numchild", "1");
|
2009-06-03 12:46:55 +02:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-03 12:46:55 +02:00
|
|
|
for (int row = 0; row < rowCount; ++row) {
|
|
|
|
for (int column = 0; column < columnCount; ++column) {
|
|
|
|
QModelIndex child = m->index(row, column, mi);
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("name");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("[").put(row).put(",").put(column).put("]");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
//d.putItem("numchild", (m->hasChildren(child) ? "1" : "0"));
|
|
|
|
d.putItem("numchild", "1");
|
|
|
|
d.beginItem("addr");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("$").put(child.row()).put(",").put(child.column()).put(",")
|
|
|
|
.put(child.internalPointer()).put(",").put(child.model());
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", NS"QAbstractItem");
|
|
|
|
d.putItem("value", m->data(mi, Qt::DisplayRole).toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
2009-06-03 12:46:55 +02:00
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
}
|
2009-06-23 10:24:25 +02:00
|
|
|
/*
|
2009-06-03 12:46:55 +02:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "DisplayRole");
|
|
|
|
d.putItem("numchild", 0);
|
|
|
|
d.putItem("value", m->data(mi, Qt::DisplayRole).toString());
|
|
|
|
d.putItem("valueencoded", 2);
|
|
|
|
d.putItem("type", NS"QString");
|
2009-06-03 12:46:55 +02:00
|
|
|
d.endHash();
|
2009-06-23 10:24:25 +02:00
|
|
|
*/
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-06-03 12:46:55 +02:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQAbstractItemModel(QDumper &d)
|
|
|
|
{
|
|
|
|
const QAbstractItemModel &m = *reinterpret_cast<const QAbstractItemModel *>(d.data);
|
|
|
|
|
|
|
|
const int rowCount = m.rowCount();
|
|
|
|
if (rowCount < 0)
|
|
|
|
return;
|
|
|
|
const int columnCount = m.columnCount();
|
|
|
|
if (columnCount < 0)
|
|
|
|
return;
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QAbstractItemModel");
|
|
|
|
d.beginItem("value");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(").put(rowCount).put(",").put(columnCount).put(")");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("numchild", "1");
|
2009-06-03 12:46:55 +02:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-03 12:46:55 +02:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("numchild", "1");
|
|
|
|
d.putItem("name", NS"QObject");
|
|
|
|
d.putItem("addr", d.data);
|
|
|
|
d.putItem("value", m.objectName());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QObject");
|
|
|
|
d.putItem("displayedtype", m.metaObject()->className());
|
2009-06-03 12:46:55 +02:00
|
|
|
d.endHash();
|
|
|
|
for (int row = 0; row < rowCount; ++row) {
|
|
|
|
for (int column = 0; column < columnCount; ++column) {
|
|
|
|
QModelIndex mi = m.index(row, column);
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("name");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("[").put(row).put(",").put(column).put("]");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("value", m.data(mi, Qt::DisplayRole).toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
//d.putItem("numchild", (m.hasChildren(mi) ? "1" : "0"));
|
|
|
|
d.putItem("numchild", "1");
|
|
|
|
d.beginItem("addr");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("$").put(mi.row()).put(",").put(mi.column()).put(",");
|
|
|
|
d.put(mi.internalPointer()).put(",").put(mi.model());
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", NS"QAbstractItem");
|
2009-06-03 12:46:55 +02:00
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-06-03 12:46:55 +02:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQByteArray(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
const QByteArray &ba = *reinterpret_cast<const QByteArray *>(d.data);
|
|
|
|
|
|
|
|
if (!ba.isEmpty()) {
|
|
|
|
qCheckAccess(ba.constData());
|
|
|
|
qCheckAccess(ba.constData() + ba.size());
|
|
|
|
}
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("value");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (ba.size() <= 100)
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(ba);
|
2008-12-02 12:01:29 +01:00
|
|
|
else
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(ba.left(100)).put(" <size: ").put(ba.size()).put(", cut...>");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("valueencoded", "1");
|
|
|
|
d.putItem("type", NS"QByteArray");
|
|
|
|
d.putItem("numchild", ba.size());
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-07-08 17:27:45 +02:00
|
|
|
d.putItem("childtype", "char");
|
|
|
|
d.putItem("childnumchild", "0");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
char buf[20];
|
|
|
|
for (int i = 0; i != ba.size(); ++i) {
|
|
|
|
unsigned char c = ba.at(i);
|
2009-01-21 12:16:27 +01:00
|
|
|
unsigned char u = (isprint(c) && c != '\'' && c != '"') ? c : '?';
|
2008-12-02 12:01:29 +01:00
|
|
|
sprintf(buf, "%02x (%u '%c')", c, c, u);
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
|
|
|
d.putItem("value", buf);
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-06-24 14:35:53 +02:00
|
|
|
static void qDumpQChar(QDumper &d)
|
|
|
|
{
|
2009-07-08 17:27:45 +02:00
|
|
|
qDumpInnerQCharValue(d, *reinterpret_cast<const QChar *>(d.data), "value");
|
2009-06-24 14:35:53 +02:00
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
static void qDumpQDateTime(QDumper &d)
|
|
|
|
{
|
|
|
|
#ifdef QT_NO_DATESTRING
|
|
|
|
qDumpUnknown(d);
|
|
|
|
#else
|
|
|
|
const QDateTime &date = *reinterpret_cast<const QDateTime *>(d.data);
|
|
|
|
if (date.isNull()) {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "(null)");
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", date.toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QDateTime");
|
|
|
|
d.putItem("numchild", "3");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("isNull", date.isNull());
|
|
|
|
d.putHash("toTime_t", (long)date.toTime_t());
|
|
|
|
d.putHash("toString", date.toString());
|
2009-04-28 11:21:46 +02:00
|
|
|
#if QT_VERSION >= 0x040500
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("toString_(ISO)", date.toString(Qt::ISODate));
|
|
|
|
d.putHash("toString_(SystemLocale)", date.toString(Qt::SystemLocaleDate));
|
|
|
|
d.putHash("toString_(Locale)", date.toString(Qt::LocaleDate));
|
2009-04-28 11:21:46 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "toUTC");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.putItem("exp", "(("NSX"QDateTime"NSY"*)").put(d.data).put(")"
|
2008-12-02 12:01:29 +01:00
|
|
|
"->toTimeSpec('"NS"Qt::UTC')");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QDateTime");
|
|
|
|
d.putItem("numchild", "1");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "toLocalTime");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.putItem("exp", "(("NSX"QDateTime"NSY"*)").put(d.data).put(")"
|
2008-12-02 12:01:29 +01:00
|
|
|
"->toTimeSpec('"NS"Qt::LocalTime')");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QDateTime");
|
|
|
|
d.putItem("numchild", "1");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
#endif
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
#endif // ifdef QT_NO_DATESTRING
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQDir(QDumper &d)
|
|
|
|
{
|
|
|
|
const QDir &dir = *reinterpret_cast<const QDir *>(d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", dir.path());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QDir");
|
|
|
|
d.putItem("numchild", "3");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("absolutePath", dir.absolutePath());
|
|
|
|
d.putHash("canonicalPath", dir.canonicalPath());
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQFile(QDumper &d)
|
|
|
|
{
|
|
|
|
const QFile &file = *reinterpret_cast<const QFile *>(d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", file.fileName());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QFile");
|
|
|
|
d.putItem("numchild", "2");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("fileName", file.fileName());
|
|
|
|
d.putHash("exists", file.exists());
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQFileInfo(QDumper &d)
|
|
|
|
{
|
|
|
|
const QFileInfo &info = *reinterpret_cast<const QFileInfo *>(d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", info.filePath());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QFileInfo");
|
|
|
|
d.putItem("numchild", "3");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("absolutePath", info.absolutePath());
|
|
|
|
d.putHash("absoluteFilePath", info.absoluteFilePath());
|
|
|
|
d.putHash("canonicalPath", info.canonicalPath());
|
|
|
|
d.putHash("canonicalFilePath", info.canonicalFilePath());
|
|
|
|
d.putHash("completeBaseName", info.completeBaseName());
|
|
|
|
d.putHash("completeSuffix", info.completeSuffix());
|
|
|
|
d.putHash("baseName", info.baseName());
|
2008-12-02 12:01:29 +01:00
|
|
|
#ifdef Q_OS_MACX
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("isBundle", info.isBundle());
|
|
|
|
d.putHash("bundleName", info.bundleName());
|
2008-12-02 12:01:29 +01:00
|
|
|
#endif
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("completeSuffix", info.completeSuffix());
|
|
|
|
d.putHash("fileName", info.fileName());
|
|
|
|
d.putHash("filePath", info.filePath());
|
|
|
|
d.putHash("group", info.group());
|
|
|
|
d.putHash("owner", info.owner());
|
|
|
|
d.putHash("path", info.path());
|
|
|
|
|
|
|
|
d.putHash("groupid", (long)info.groupId());
|
|
|
|
d.putHash("ownerid", (long)info.ownerId());
|
2008-12-02 12:01:29 +01:00
|
|
|
//QFile::Permissions permissions () const
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("permissions", (long)info.permissions());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
//QDir absoluteDir () const
|
|
|
|
//QDir dir () const
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("caching", info.caching());
|
|
|
|
d.putHash("exists", info.exists());
|
|
|
|
d.putHash("isAbsolute", info.isAbsolute());
|
|
|
|
d.putHash("isDir", info.isDir());
|
|
|
|
d.putHash("isExecutable", info.isExecutable());
|
|
|
|
d.putHash("isFile", info.isFile());
|
|
|
|
d.putHash("isHidden", info.isHidden());
|
|
|
|
d.putHash("isReadable", info.isReadable());
|
|
|
|
d.putHash("isRelative", info.isRelative());
|
|
|
|
d.putHash("isRoot", info.isRoot());
|
|
|
|
d.putHash("isSymLink", info.isSymLink());
|
|
|
|
d.putHash("isWritable", info.isWritable());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "created");
|
|
|
|
d.putItem("value", info.created().toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QFileInfo"NSY"*)").put(d.data).put(")->created()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", NS"QDateTime");
|
|
|
|
d.putItem("numchild", "1");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "lastModified");
|
|
|
|
d.putItem("value", info.lastModified().toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QFileInfo"NSY"*)").put(d.data).put(")->lastModified()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", NS"QDateTime");
|
|
|
|
d.putItem("numchild", "1");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "lastRead");
|
|
|
|
d.putItem("value", info.lastRead().toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QFileInfo"NSY"*)").put(d.data).put(")->lastRead()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", NS"QDateTime");
|
|
|
|
d.putItem("numchild", "1");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isOptimizedIntKey(const char *keyType)
|
|
|
|
{
|
|
|
|
return isEqual(keyType, "int")
|
|
|
|
#if defined(Q_BYTE_ORDER) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
|
|
|
|| isEqual(keyType, "short")
|
|
|
|
|| isEqual(keyType, "ushort")
|
|
|
|
#endif
|
|
|
|
|| isEqual(keyType, "uint");
|
|
|
|
}
|
|
|
|
|
|
|
|
int hashOffset(bool optimizedIntKey, bool forKey, unsigned keySize, unsigned valueSize)
|
|
|
|
{
|
|
|
|
// int-key optimization, small value
|
|
|
|
struct NodeOS { void *next; uint k; uint v; } nodeOS;
|
|
|
|
// int-key optimiatzion, large value
|
|
|
|
struct NodeOL { void *next; uint k; void *v; } nodeOL;
|
|
|
|
// no optimization, small value
|
|
|
|
struct NodeNS { void *next; uint h; uint k; uint v; } nodeNS;
|
|
|
|
// no optimization, large value
|
|
|
|
struct NodeNL { void *next; uint h; uint k; void *v; } nodeNL;
|
|
|
|
// complex key
|
|
|
|
struct NodeL { void *next; uint h; void *k; void *v; } nodeL;
|
|
|
|
|
|
|
|
if (forKey) {
|
|
|
|
// offsetof(...,...) not yet in Standard C++
|
|
|
|
const ulong nodeOSk ( (char *)&nodeOS.k - (char *)&nodeOS );
|
|
|
|
const ulong nodeOLk ( (char *)&nodeOL.k - (char *)&nodeOL );
|
|
|
|
const ulong nodeNSk ( (char *)&nodeNS.k - (char *)&nodeNS );
|
|
|
|
const ulong nodeNLk ( (char *)&nodeNL.k - (char *)&nodeNL );
|
|
|
|
const ulong nodeLk ( (char *)&nodeL.k - (char *)&nodeL );
|
|
|
|
if (optimizedIntKey)
|
|
|
|
return valueSize > sizeof(int) ? nodeOLk : nodeOSk;
|
|
|
|
if (keySize > sizeof(int))
|
|
|
|
return nodeLk;
|
|
|
|
return valueSize > sizeof(int) ? nodeNLk : nodeNSk;
|
|
|
|
} else {
|
|
|
|
const ulong nodeOSv ( (char *)&nodeOS.v - (char *)&nodeOS );
|
|
|
|
const ulong nodeOLv ( (char *)&nodeOL.v - (char *)&nodeOL );
|
|
|
|
const ulong nodeNSv ( (char *)&nodeNS.v - (char *)&nodeNS );
|
|
|
|
const ulong nodeNLv ( (char *)&nodeNL.v - (char *)&nodeNL );
|
|
|
|
const ulong nodeLv ( (char *)&nodeL.v - (char *)&nodeL );
|
|
|
|
if (optimizedIntKey)
|
|
|
|
return valueSize > sizeof(int) ? nodeOLv : nodeOSv;
|
|
|
|
if (keySize > sizeof(int))
|
|
|
|
return nodeLv;
|
|
|
|
return valueSize > sizeof(int) ? nodeNLv : nodeNSv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-02 16:38:15 +02:00
|
|
|
#ifdef Q_CC_MSVC
|
|
|
|
# define MAP_NODE_TYPE_END ">"
|
|
|
|
#else
|
|
|
|
# define MAP_NODE_TYPE_END " >"
|
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQHash(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
QHashData *h = *reinterpret_cast<QHashData *const*>(d.data);
|
|
|
|
const char *keyType = d.templateParameters[0];
|
|
|
|
const char *valueType = d.templateParameters[1];
|
|
|
|
|
|
|
|
qCheckPointer(h->fakeNext);
|
|
|
|
qCheckPointer(h->buckets);
|
|
|
|
|
|
|
|
unsigned keySize = d.extraInt[0];
|
|
|
|
unsigned valueSize = d.extraInt[1];
|
|
|
|
|
|
|
|
int n = h->size;
|
|
|
|
|
|
|
|
if (n < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (n > 0) {
|
|
|
|
qCheckPointer(h->fakeNext);
|
|
|
|
qCheckPointer(*h->buckets);
|
|
|
|
}
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("numchild", n);
|
2009-07-06 17:36:50 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
if (n > 1000)
|
|
|
|
n = 1000;
|
2009-07-06 17:36:50 +02:00
|
|
|
const bool isSimpleKey = isSimpleType(keyType);
|
|
|
|
const bool isSimpleValue = isSimpleType(valueType);
|
|
|
|
const bool opt = isOptimizedIntKey(keyType);
|
|
|
|
const int keyOffset = hashOffset(opt, true, keySize, valueSize);
|
|
|
|
const int valueOffset = hashOffset(opt, false, keySize, valueSize);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("extra");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("isSimpleKey: ").put(isSimpleKey);
|
|
|
|
d.put(" isSimpleValue: ").put(isSimpleValue);
|
|
|
|
d.put(" valueType: '").put(isSimpleValue);
|
|
|
|
d.put(" keySize: ").put(keyOffset);
|
|
|
|
d.put(" valueOffset: ").put(valueOffset);
|
|
|
|
d.put(" opt: ").put(opt);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
QHashData::Node *node = h->firstNode();
|
|
|
|
QHashData::Node *end = reinterpret_cast<QHashData::Node *>(h);
|
|
|
|
int i = 0;
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
while (node != end) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2009-01-28 16:55:09 +01:00
|
|
|
qDumpInnerValueHelper(d, keyType, addOffset(node, keyOffset), "key");
|
|
|
|
qDumpInnerValueHelper(d, valueType, addOffset(node, valueOffset));
|
|
|
|
if (isSimpleKey && isSimpleValue) {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", valueType);
|
|
|
|
d.putItem("addr", addOffset(node, valueOffset));
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("addr", node);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("type");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("'"NS"QHashNode<").put(keyType).put(",")
|
2009-07-02 16:38:15 +02:00
|
|
|
.put(valueType).put(MAP_NODE_TYPE_END"'");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.endHash();
|
|
|
|
++i;
|
|
|
|
node = QHashData::nextNode(node);
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQHashNode(QDumper &d)
|
|
|
|
{
|
|
|
|
const QHashData *h = reinterpret_cast<const QHashData *>(d.data);
|
|
|
|
const char *keyType = d.templateParameters[0];
|
|
|
|
const char *valueType = d.templateParameters[1];
|
|
|
|
|
2009-01-28 17:34:23 +01:00
|
|
|
unsigned keySize = d.extraInt[0];
|
|
|
|
unsigned valueSize = d.extraInt[1];
|
|
|
|
bool opt = isOptimizedIntKey(keyType);
|
|
|
|
int keyOffset = hashOffset(opt, true, keySize, valueSize);
|
|
|
|
int valueOffset = hashOffset(opt, false, keySize, valueSize);
|
2009-06-26 10:50:58 +02:00
|
|
|
if (isSimpleType(valueType))
|
2009-01-28 17:34:23 +01:00
|
|
|
qDumpInnerValueHelper(d, valueType, addOffset(h, valueOffset));
|
|
|
|
else
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "");
|
2009-01-28 17:34:23 +01:00
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("numchild", 2);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-05-05 18:49:35 +02:00
|
|
|
// there is a hash specialization in case the keys are integers or shorts
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "key");
|
|
|
|
d.putItem("type", keyType);
|
|
|
|
d.putItem("addr", addOffset(h, keyOffset));
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "value");
|
|
|
|
d.putItem("type", valueType);
|
|
|
|
d.putItem("addr", addOffset(h, valueOffset));
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-06-18 13:22:58 +02:00
|
|
|
#if USE_QT_GUI
|
2008-12-02 12:01:29 +01:00
|
|
|
static void qDumpQImage(QDumper &d)
|
|
|
|
{
|
|
|
|
const QImage &im = *reinterpret_cast<const QImage *>(d.data);
|
2009-07-01 12:49:41 +02:00
|
|
|
d.beginItem("value");
|
|
|
|
d.put("(").put(im.width()).put("x").put(im.height()).put(")");
|
|
|
|
d.endItem();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QImage");
|
|
|
|
d.putItem("numchild", "1");
|
2009-05-29 16:24:46 +02:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-05-29 16:24:46 +02:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "data");
|
|
|
|
d.putItem("type", NS "QImageData");
|
|
|
|
d.putItem("addr", d.data);
|
2009-05-29 16:24:46 +02:00
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
2009-06-18 13:22:58 +02:00
|
|
|
#endif
|
2009-05-29 16:24:46 +02:00
|
|
|
|
2009-06-18 13:22:58 +02:00
|
|
|
#if USE_QT_GUI
|
2009-05-29 16:24:46 +02:00
|
|
|
static void qDumpQImageData(QDumper &d)
|
|
|
|
{
|
|
|
|
const QImage &im = *reinterpret_cast<const QImage *>(d.data);
|
|
|
|
const QByteArray ba(QByteArray::fromRawData((const char*)im.bits(), im.numBytes()));
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QImageData");
|
|
|
|
d.putItem("numchild", "0");
|
2009-05-29 16:24:46 +02:00
|
|
|
#if 1
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "<hover here>");
|
|
|
|
d.putItem("valuetooltipencoded", "1");
|
|
|
|
d.putItem("valuetooltipsize", ba.size());
|
|
|
|
d.putItem("valuetooltip", ba);
|
2009-05-29 16:24:46 +02:00
|
|
|
#else
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("valueencoded", "1");
|
|
|
|
d.putItem("value", ba);
|
2009-05-29 16:24:46 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
d.disarm();
|
|
|
|
}
|
2009-06-18 13:22:58 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQList(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
// This uses the knowledge that QList<T> has only a single member
|
|
|
|
// of type union { QListData p; QListData::Data *d; };
|
2009-04-29 14:15:09 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
const QListData &ldata = *reinterpret_cast<const QListData*>(d.data);
|
|
|
|
const QListData::Data *pdata =
|
|
|
|
*reinterpret_cast<const QListData::Data* const*>(d.data);
|
2009-04-29 14:15:09 +02:00
|
|
|
qCheckAccess(pdata);
|
2008-12-02 12:01:29 +01:00
|
|
|
int nn = ldata.size();
|
|
|
|
if (nn < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (nn > 0) {
|
|
|
|
qCheckAccess(ldata.d->array);
|
|
|
|
//qCheckAccess(ldata.d->array[0]);
|
|
|
|
//qCheckAccess(ldata.d->array[nn - 1]);
|
|
|
|
#if QT_VERSION >= 0x040400
|
|
|
|
if (ldata.d->ref._q_value <= 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int n = nn;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", n);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
unsigned innerSize = d.extraInt[0];
|
|
|
|
bool innerTypeIsPointer = isPointerType(d.innertype);
|
|
|
|
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
|
|
|
|
|
|
|
// The exact condition here is:
|
|
|
|
// QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
|
|
|
|
// but this data is available neither in the compiled binary nor
|
|
|
|
// in the frontend.
|
|
|
|
// So as first approximation only do the 'isLarge' check:
|
|
|
|
bool isInternal = innerSize <= int(sizeof(void*))
|
|
|
|
&& isMovableType(d.innertype);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("internal", (int)isInternal);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (n > 1000)
|
|
|
|
n = 1000;
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(n ? d.innertype : 0);
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int i = 0; i != n; ++i) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (innerTypeIsPointer) {
|
|
|
|
void *p = ldata.d->array + i + pdata->begin;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("saddr", p);
|
2009-06-19 15:12:52 +02:00
|
|
|
if (*(void**)p) {
|
2009-06-26 11:32:51 +02:00
|
|
|
//d.putItem("value","@").put(p);
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValue(d, strippedInnerType.data(), deref(p));
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "<null>");
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
void *p = ldata.d->array + i + pdata->begin;
|
|
|
|
if (isInternal) {
|
|
|
|
//qDumpInnerValue(d, d.innertype, p);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", p);
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueHelper(d, d.innertype, p);
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
|
|
|
//qDumpInnerValue(d, d.innertype, deref(p));
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", deref(p));
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueHelper(d, d.innertype, deref(p));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
d.endHash();
|
|
|
|
}
|
2008-12-10 16:31:50 +01:00
|
|
|
if (n < nn)
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQLinkedList(QDumper &d)
|
2009-01-08 11:50:20 +01:00
|
|
|
{
|
|
|
|
// This uses the knowledge that QLinkedList<T> has only a single member
|
|
|
|
// of type union { QLinkedListData *d; QLinkedListNode<T> *e; };
|
|
|
|
const QLinkedListData *ldata =
|
|
|
|
reinterpret_cast<const QLinkedListData*>(deref(d.data));
|
|
|
|
int nn = ldata->size;
|
|
|
|
if (nn < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2009-01-08 11:50:20 +01:00
|
|
|
|
|
|
|
int n = nn;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", n);
|
2009-01-08 11:50:20 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-01-28 16:55:09 +01:00
|
|
|
//unsigned innerSize = d.extraInt[0];
|
|
|
|
//bool innerTypeIsPointer = isPointerType(d.innertype);
|
2009-01-08 11:50:20 +01:00
|
|
|
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
|
|
|
const char *stripped =
|
|
|
|
isPointerType(d.innertype) ? strippedInnerType.data() : 0;
|
|
|
|
|
|
|
|
if (n > 1000)
|
|
|
|
n = 1000;
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(d.innertype);
|
2009-01-08 11:50:20 +01:00
|
|
|
const void *p = deref(ldata);
|
|
|
|
for (int i = 0; i != n; ++i) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2009-01-08 11:50:20 +01:00
|
|
|
const void *addr = addOffset(p, 2 * sizeof(void*));
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueOrPointer(d, d.innertype, stripped, addr);
|
2009-01-08 11:50:20 +01:00
|
|
|
p = deref(p);
|
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
if (n < nn)
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-01-08 11:50:20 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
static void qDumpQLocale(QDumper &d)
|
|
|
|
{
|
|
|
|
const QLocale &locale = *reinterpret_cast<const QLocale *>(d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", locale.name());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QLocale");
|
|
|
|
d.putItem("numchild", "8");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "country");
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QLocale"NSY"*)").put(d.data).put(")->country()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "language");
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QLocale"NSY"*)").put(d.data).put(")->language()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "measurementSystem");
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QLocale"NSY"*)").put(d.data).put(")->measurementSystem()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "numberOptions");
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QLocale"NSY"*)").put(d.data).put(")->numberOptions()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("timeFormat_(short)", locale.timeFormat(QLocale::ShortFormat));
|
|
|
|
d.putHash("timeFormat_(long)", locale.timeFormat(QLocale::LongFormat));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("decimalPoint", locale.decimalPoint());
|
|
|
|
d.putHash("exponential", locale.exponential());
|
|
|
|
d.putHash("percent", locale.percent());
|
|
|
|
d.putHash("zeroDigit", locale.zeroDigit());
|
|
|
|
d.putHash("groupSeparator", locale.groupSeparator());
|
|
|
|
d.putHash("negativeSign", locale.negativeSign());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQMapNode(QDumper &d)
|
2009-01-07 16:29:14 +01:00
|
|
|
{
|
|
|
|
const QMapData *h = reinterpret_cast<const QMapData *>(d.data);
|
|
|
|
const char *keyType = d.templateParameters[0];
|
|
|
|
const char *valueType = d.templateParameters[1];
|
|
|
|
|
|
|
|
qCheckAccess(h->backward);
|
|
|
|
qCheckAccess(h->forward[0]);
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "");
|
|
|
|
d.putItem("numchild", 2);
|
2009-01-07 16:29:14 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
unsigned mapnodesize = d.extraInt[2];
|
|
|
|
unsigned valueOff = d.extraInt[3];
|
|
|
|
|
|
|
|
unsigned keyOffset = 2 * sizeof(void*) - mapnodesize;
|
|
|
|
unsigned valueOffset = 2 * sizeof(void*) - mapnodesize + valueOff;
|
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(d.innertype);
|
2009-01-07 16:29:14 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "key");
|
2009-01-07 16:29:14 +01:00
|
|
|
qDumpInnerValue(d, keyType, addOffset(h, keyOffset));
|
|
|
|
|
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "value");
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValue(d, valueType, addOffset(h, valueOffset));
|
2009-01-07 16:29:14 +01:00
|
|
|
d.endHash();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-01-07 16:29:14 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQMap(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
QMapData *h = *reinterpret_cast<QMapData *const*>(d.data);
|
|
|
|
const char *keyType = d.templateParameters[0];
|
|
|
|
const char *valueType = d.templateParameters[1];
|
|
|
|
|
|
|
|
int n = h->size;
|
|
|
|
|
|
|
|
if (n < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (n > 0) {
|
|
|
|
qCheckAccess(h->backward);
|
|
|
|
qCheckAccess(h->forward[0]);
|
|
|
|
qCheckPointer(h->backward->backward);
|
|
|
|
qCheckPointer(h->forward[0]->backward);
|
|
|
|
}
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("numchild", n);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
if (n > 1000)
|
|
|
|
n = 1000;
|
|
|
|
|
|
|
|
//unsigned keySize = d.extraInt[0];
|
|
|
|
//unsigned valueSize = d.extraInt[1];
|
|
|
|
unsigned mapnodesize = d.extraInt[2];
|
|
|
|
unsigned valueOff = d.extraInt[3];
|
|
|
|
|
2009-01-28 17:34:23 +01:00
|
|
|
bool isSimpleKey = isSimpleType(keyType);
|
|
|
|
bool isSimpleValue = isSimpleType(valueType);
|
2008-12-02 12:01:29 +01:00
|
|
|
// both negative:
|
|
|
|
int keyOffset = 2 * sizeof(void*) - int(mapnodesize);
|
|
|
|
int valueOffset = 2 * sizeof(void*) - int(mapnodesize) + valueOff;
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("extra");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("simplekey: ").put(isSimpleKey).put(" isSimpleValue: ").put(isSimpleValue);
|
|
|
|
d.put(" keyOffset: ").put(keyOffset).put(" valueOffset: ").put(valueOffset);
|
|
|
|
d.put(" mapnodesize: ").put(mapnodesize);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
QMapData::Node *node = reinterpret_cast<QMapData::Node *>(h->forward[0]);
|
|
|
|
QMapData::Node *end = reinterpret_cast<QMapData::Node *>(h);
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
while (node != end) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2009-01-28 17:34:23 +01:00
|
|
|
qDumpInnerValueHelper(d, keyType, addOffset(node, keyOffset), "key");
|
|
|
|
qDumpInnerValueHelper(d, valueType, addOffset(node, valueOffset));
|
|
|
|
if (isSimpleKey && isSimpleValue) {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", valueType);
|
|
|
|
d.putItem("addr", addOffset(node, valueOffset));
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-01-07 15:03:49 +01:00
|
|
|
#if QT_VERSION >= 0x040500
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("addr", node);
|
2008-12-02 12:01:29 +01:00
|
|
|
// actually, any type (even 'char') will do...
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("type");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(NS"QMapNode<").put(keyType).put(",");
|
2009-07-02 16:38:15 +02:00
|
|
|
d.put(valueType).put(MAP_NODE_TYPE_END);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
#else
|
|
|
|
d.beginItem("type");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(NS"QMapData::Node<").put(keyType).put(",");
|
2009-07-02 16:38:15 +02:00
|
|
|
d.put(valueType).put(MAP_NODE_TYPE_END);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("*('"NS"QMapData::Node<").put(keyType).put(",");
|
|
|
|
d.put(valueType).put(" >'*)").put(node);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2009-01-07 15:03:49 +01:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.endHash();
|
|
|
|
|
|
|
|
++i;
|
|
|
|
node = node->forward[0];
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQMultiMap(QDumper &d)
|
2009-01-07 16:29:14 +01:00
|
|
|
{
|
2009-04-29 14:31:11 +02:00
|
|
|
qDumpQMap(d);
|
2009-01-07 16:29:14 +01:00
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
static void qDumpQModelIndex(QDumper &d)
|
|
|
|
{
|
|
|
|
const QModelIndex *mi = reinterpret_cast<const QModelIndex *>(d.data);
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QModelIndex");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (mi->isValid()) {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("value");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(").put(mi->row()).put(", ").put(mi->column()).put(")");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("numchild", 5);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("row", mi->row());
|
|
|
|
d.putHash("column", mi->column());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "parent");
|
2008-12-02 12:01:29 +01:00
|
|
|
const QModelIndex parent = mi->parent();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("value");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (parent.isValid())
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(").put(mi->row()).put(", ").put(mi->column()).put(")");
|
2008-12-02 12:01:29 +01:00
|
|
|
else
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("<invalid>");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(("NSX"QModelIndex"NSY"*)").put(d.data).put(")->parent()");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", NS"QModelIndex");
|
|
|
|
d.putItem("numchild", "1");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("internalId", QString::number(mi->internalId(), 10));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "model");
|
|
|
|
d.putItem("value", static_cast<const void *>(mi->model()));
|
|
|
|
d.putItem("type", NS"QAbstractItemModel*");
|
|
|
|
d.putItem("numchild", "1");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
} else {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "<invalid>");
|
|
|
|
d.putItem("numchild", 0);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQObject(QDumper &d)
|
|
|
|
{
|
|
|
|
const QObject *ob = reinterpret_cast<const QObject *>(d.data);
|
|
|
|
const QMetaObject *mo = ob->metaObject();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", ob->objectName());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QObject");
|
|
|
|
d.putItem("displayedtype", mo->className());
|
|
|
|
d.putItem("numchild", 4);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
int slotCount = 0;
|
|
|
|
int signalCount = 0;
|
|
|
|
for (int i = mo->methodCount(); --i >= 0; ) {
|
|
|
|
QMetaMethod::MethodType mt = mo->method(i).methodType();
|
|
|
|
signalCount += (mt == QMetaMethod::Signal);
|
|
|
|
slotCount += (mt == QMetaMethod::Slot);
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "properties");
|
2009-07-09 09:11:22 +02:00
|
|
|
// using 'addr' does not work in gdb as 'exp' is recreated as
|
2009-07-08 17:27:45 +02:00
|
|
|
// (type *)addr, and here we have different 'types':
|
|
|
|
// QObject vs QObjectPropertyList!
|
2009-07-09 09:11:22 +02:00
|
|
|
d.putItem("addr", d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QObjectPropertyList");
|
|
|
|
d.putItemCount("value", mo->propertyCount());
|
|
|
|
d.putItem("numchild", mo->propertyCount());
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "signals");
|
2009-07-09 09:11:22 +02:00
|
|
|
d.putItem("addr", d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QObjectSignalList");
|
|
|
|
d.putItemCount("value", signalCount);
|
|
|
|
d.putItem("numchild", signalCount);
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "slots");
|
2009-07-09 09:11:22 +02:00
|
|
|
d.putItem("addr", d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QObjectSlotList");
|
|
|
|
d.putItemCount("value", slotCount);
|
|
|
|
d.putItem("numchild", slotCount);
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
2009-07-06 17:36:50 +02:00
|
|
|
const QObjectList objectChildren = ob->children();
|
|
|
|
if (!objectChildren.empty()) {
|
2009-05-05 16:39:51 +02:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "children");
|
2009-07-09 09:11:22 +02:00
|
|
|
d.putItem("addr", d.data);
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("type", NS"QObjectChildList");
|
|
|
|
d.putItemCount("value", objectChildren.size());
|
|
|
|
d.putItem("numchild", objectChildren.size());
|
2009-05-05 16:39:51 +02:00
|
|
|
d.endHash();
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "parent");
|
2008-12-02 12:01:29 +01:00
|
|
|
qDumpInnerValueHelper(d, NS"QObject *", ob->parent());
|
|
|
|
d.endHash();
|
|
|
|
#if 1
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "className");
|
2009-07-09 10:26:54 +02:00
|
|
|
d.putItem("value", ob->metaObject()->className());
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", "");
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
#endif
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-07-06 17:36:50 +02:00
|
|
|
#if USE_QT_GUI
|
|
|
|
static const char *sizePolicyEnumValue(QSizePolicy::Policy p)
|
|
|
|
{
|
|
|
|
switch (p) {
|
|
|
|
case QSizePolicy::Fixed:
|
|
|
|
return "Fixed";
|
|
|
|
case QSizePolicy::Minimum:
|
|
|
|
return "Minimum";
|
|
|
|
case QSizePolicy::Maximum:
|
|
|
|
return "Maximum";
|
|
|
|
case QSizePolicy::Preferred:
|
|
|
|
return "Preferred";
|
|
|
|
case QSizePolicy::Expanding:
|
|
|
|
return "Expanding";
|
|
|
|
case QSizePolicy::MinimumExpanding:
|
|
|
|
return "MinimumExpanding";
|
|
|
|
case QSizePolicy::Ignored:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return "Ignored";
|
|
|
|
}
|
|
|
|
|
|
|
|
static QString sizePolicyValue(const QSizePolicy &sp)
|
|
|
|
{
|
|
|
|
QString rc;
|
|
|
|
QTextStream str(&rc);
|
|
|
|
// Display as in Designer
|
|
|
|
str << '[' << sizePolicyEnumValue(sp.horizontalPolicy())
|
|
|
|
<< ", " << sizePolicyEnumValue(sp.verticalPolicy())
|
|
|
|
<< ", " << sp.horizontalStretch() << ", " << sp.verticalStretch() << ']';
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void qDumpQVariantHelper(const QVariant *v, QString *value,
|
|
|
|
QString *exp, int *numchild)
|
|
|
|
{
|
|
|
|
switch (v->type()) {
|
|
|
|
case QVariant::Invalid:
|
|
|
|
*value = QLatin1String("<invalid>");
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
case QVariant::String:
|
|
|
|
*value = QLatin1Char('"') + v->toString() + QLatin1Char('"');
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
#if QT_VERSION >= 0x040500
|
|
|
|
case QVariant::StringList:
|
|
|
|
*exp = QString(QLatin1String("(*('"NS"QStringList'*)%1)"))
|
|
|
|
.arg((quintptr)v);
|
|
|
|
*numchild = v->toStringList().size();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case QVariant::Int:
|
|
|
|
*value = QString::number(v->toInt());
|
|
|
|
*numchild= 0;
|
|
|
|
break;
|
|
|
|
case QVariant::Double:
|
|
|
|
*value = QString::number(v->toDouble());
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
case QVariant::Point: {
|
|
|
|
const QPoint p = v->toPoint();
|
|
|
|
*value = QString::fromLatin1("%1, %2").arg(p.x()).arg(p.y());
|
|
|
|
}
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
case QVariant::Size: {
|
|
|
|
const QSize size = v->toSize();
|
2009-07-09 10:26:54 +02:00
|
|
|
*value = QString::fromLatin1("%1x%2")
|
|
|
|
.arg(size.width()).arg(size.height());
|
2009-07-06 17:36:50 +02:00
|
|
|
}
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
case QVariant::Rect: {
|
|
|
|
const QRect rect = v->toRect();
|
2009-07-09 10:26:54 +02:00
|
|
|
*value = QString::fromLatin1("%1x%2+%3+%4")
|
|
|
|
.arg(rect.width()).arg(rect.height())
|
|
|
|
.arg(rect.x()).arg(rect.y());
|
2009-07-06 17:36:50 +02:00
|
|
|
}
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
case QVariant::PointF: {
|
|
|
|
const QPointF p = v->toPointF();
|
|
|
|
*value = QString::fromLatin1("%1, %2").arg(p.x()).arg(p.y());
|
|
|
|
}
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QVariant::SizeF: {
|
|
|
|
const QSizeF size = v->toSizeF();
|
2009-07-09 10:26:54 +02:00
|
|
|
*value = QString::fromLatin1("%1x%2")
|
|
|
|
.arg(size.width()).arg(size.height());
|
2009-07-06 17:36:50 +02:00
|
|
|
}
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
case QVariant::RectF: {
|
|
|
|
const QRectF rect = v->toRectF();
|
2009-07-09 10:26:54 +02:00
|
|
|
*value = QString::fromLatin1("%1x%2+%3+%4")
|
|
|
|
.arg(rect.width()).arg(rect.height())
|
|
|
|
.arg(rect.x()).arg(rect.y());
|
2009-07-06 17:36:50 +02:00
|
|
|
}
|
|
|
|
*numchild = 0;
|
|
|
|
break;
|
|
|
|
#if USE_QT_GUI
|
|
|
|
case QVariant::Font:
|
|
|
|
*value = qvariant_cast<QFont>(*v).toString();
|
|
|
|
break;
|
|
|
|
case QVariant::Color:
|
|
|
|
*value = qvariant_cast<QColor>(*v).name();
|
|
|
|
break;
|
|
|
|
case QVariant::KeySequence:
|
|
|
|
*value = qvariant_cast<QKeySequence>(*v).toString();
|
|
|
|
break;
|
|
|
|
case QVariant::SizePolicy:
|
|
|
|
*value = sizePolicyValue(qvariant_cast<QSizePolicy>(*v));
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default: {
|
|
|
|
char buf[1000];
|
|
|
|
const char *format = (v->typeName()[0] == 'Q')
|
|
|
|
? "'"NS"%s "NS"qVariantValue<"NS"%s >'(*('"NS"QVariant'*)%p)"
|
|
|
|
: "'%s "NS"qVariantValue<%s >'(*('"NS"QVariant'*)%p)";
|
|
|
|
qsnprintf(buf, sizeof(buf) - 1, format, v->typeName(), v->typeName(), v);
|
|
|
|
*exp = QLatin1String(buf);
|
|
|
|
*numchild = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQVariant(QDumper &d, const QVariant *v)
|
|
|
|
{
|
|
|
|
QString value;
|
|
|
|
QString exp;
|
|
|
|
int numchild = 0;
|
|
|
|
qDumpQVariantHelper(v, &value, &exp, &numchild);
|
|
|
|
bool isInvalid = (v->typeName() == 0);
|
|
|
|
if (isInvalid) {
|
|
|
|
d.putItem("value", "(invalid)");
|
|
|
|
} else if (value.isEmpty()) {
|
|
|
|
d.beginItem("value");
|
|
|
|
d.put("(").put(v->typeName()).put(") ");
|
|
|
|
d.endItem();
|
|
|
|
} else {
|
|
|
|
QByteArray ba;
|
|
|
|
ba += '(';
|
|
|
|
ba += v->typeName();
|
|
|
|
ba += ") ";
|
|
|
|
ba += qPrintable(value);
|
|
|
|
d.putItem("value", ba);
|
|
|
|
d.putItem("valueencoded", "5");
|
|
|
|
}
|
|
|
|
d.putItem("type", NS"QVariant");
|
2009-07-07 11:38:01 +02:00
|
|
|
if (isInvalid || !numchild) {
|
|
|
|
d.putItem("numchild", "0");
|
|
|
|
} else {
|
|
|
|
d.putItem("numchild", "1");
|
|
|
|
if (d.dumpChildren) {
|
|
|
|
d.beginChildren();
|
|
|
|
d.beginHash();
|
|
|
|
d.putItem("name", "value");
|
|
|
|
if (!exp.isEmpty())
|
|
|
|
d.putItem("exp", qPrintable(exp));
|
|
|
|
if (!value.isEmpty()) {
|
|
|
|
d.putItem("value", value);
|
|
|
|
d.putItem("valueencoded", "4");
|
|
|
|
}
|
|
|
|
d.putItem("type", v->typeName());
|
|
|
|
d.putItem("numchild", numchild);
|
|
|
|
d.endHash();
|
|
|
|
d.endChildren();
|
2009-07-06 17:36:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void qDumpQVariant(QDumper &d)
|
|
|
|
{
|
|
|
|
qDumpQVariant(d, reinterpret_cast<const QVariant *>(d.data));
|
|
|
|
}
|
|
|
|
|
2009-07-07 11:38:01 +02:00
|
|
|
// Meta enumeration helpers
|
|
|
|
static inline void dumpMetaEnumType(QDumper &d, const QMetaEnum &me)
|
|
|
|
{
|
|
|
|
QByteArray type = me.scope();
|
|
|
|
if (!type.isEmpty())
|
|
|
|
type += "::";
|
|
|
|
type += me.name();
|
|
|
|
d.putItem("type", type.constData());
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dumpMetaEnumValue(QDumper &d, const QMetaProperty &mop,
|
|
|
|
int value)
|
|
|
|
{
|
|
|
|
|
|
|
|
const QMetaEnum me = mop.enumerator();
|
|
|
|
dumpMetaEnumType(d, me);
|
|
|
|
if (const char *enumValue = me.valueToKey(value)) {
|
|
|
|
d.putItem("value", enumValue);
|
|
|
|
} else {
|
|
|
|
d.putItem("value", value);
|
|
|
|
}
|
|
|
|
d.putItem("numchild", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dumpMetaFlagValue(QDumper &d, const QMetaProperty &mop,
|
|
|
|
int value)
|
|
|
|
{
|
|
|
|
const QMetaEnum me = mop.enumerator();
|
|
|
|
dumpMetaEnumType(d, me);
|
|
|
|
const QByteArray flagsValue = me.valueToKeys(value);
|
|
|
|
if (flagsValue.isEmpty()) {
|
|
|
|
d.putItem("value", value);
|
|
|
|
} else {
|
|
|
|
d.putItem("value", flagsValue.constData());
|
|
|
|
}
|
|
|
|
d.putItem("numchild", 0);
|
|
|
|
}
|
|
|
|
|
2009-07-06 17:36:50 +02:00
|
|
|
static void qDumpQObjectProperty(QDumper &d)
|
|
|
|
{
|
|
|
|
const QObject *ob = (const QObject *)d.data;
|
2009-07-07 11:38:01 +02:00
|
|
|
const QMetaObject *mob = ob->metaObject();
|
2009-07-06 17:36:50 +02:00
|
|
|
// extract "local.Object.property"
|
|
|
|
QString iname = d.iname;
|
|
|
|
const int dotPos = iname.lastIndexOf(QLatin1Char('.'));
|
|
|
|
if (dotPos == -1)
|
|
|
|
return;
|
|
|
|
iname.remove(0, dotPos + 1);
|
2009-07-07 11:38:01 +02:00
|
|
|
const int index = mob->indexOfProperty(iname.toAscii());
|
|
|
|
if (index == -1)
|
|
|
|
return;
|
|
|
|
const QMetaProperty mop = mob->property(index);
|
|
|
|
const QVariant value = mop.read(ob);
|
|
|
|
const bool isInteger = value.type() == QVariant::Int;
|
|
|
|
if (isInteger && mop.isEnumType()) {
|
|
|
|
dumpMetaEnumValue(d, mop, value.toInt());
|
|
|
|
} else if (isInteger && mop.isFlagType()) {
|
|
|
|
dumpMetaFlagValue(d, mop, value.toInt());
|
|
|
|
} else {
|
|
|
|
qDumpQVariant(d, &value);
|
|
|
|
}
|
2009-07-06 17:36:50 +02:00
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
static void qDumpQObjectPropertyList(QDumper &d)
|
|
|
|
{
|
|
|
|
const QObject *ob = (const QObject *)d.data;
|
|
|
|
const QMetaObject *mo = ob->metaObject();
|
2009-07-06 17:36:50 +02:00
|
|
|
const int propertyCount = mo->propertyCount();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", "<synthetic>");
|
|
|
|
d.putItem("type", NS"QObjectPropertyList");
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("numchild", propertyCount);
|
|
|
|
d.putItemCount("value", propertyCount);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-07-06 17:36:50 +02:00
|
|
|
for (int i = propertyCount; --i >= 0; ) {
|
2008-12-02 12:01:29 +01:00
|
|
|
const QMetaProperty & prop = mo->property(i);
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", prop.name());
|
2009-07-06 17:36:50 +02:00
|
|
|
switch (prop.type()) {
|
|
|
|
case QVariant::String:
|
|
|
|
d.putItem("type", prop.typeName());
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", prop.read(ob).toString());
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("numchild", "0");
|
2009-07-06 17:36:50 +02:00
|
|
|
break;
|
|
|
|
case QVariant::Bool:
|
|
|
|
d.putItem("type", prop.typeName());
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", (prop.read(ob).toBool() ? "true" : "false"));
|
|
|
|
d.putItem("numchild", "0");
|
2009-07-06 17:36:50 +02:00
|
|
|
break;
|
|
|
|
case QVariant::Int:
|
2009-07-07 11:38:01 +02:00
|
|
|
if (prop.isEnumType()) {
|
|
|
|
dumpMetaEnumValue(d, prop, prop.read(ob).toInt());
|
|
|
|
} else if (prop.isFlagType()) {
|
|
|
|
dumpMetaFlagValue(d, prop, prop.read(ob).toInt());
|
|
|
|
} else {
|
|
|
|
d.putItem("value", prop.read(ob).toInt());
|
|
|
|
d.putItem("numchild", "0");
|
|
|
|
}
|
2009-07-06 17:36:50 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
d.putItem("addr", d.data);
|
|
|
|
d.putItem("type", NS"QObjectProperty");
|
|
|
|
d.putItem("numchild", "1");
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.endHash();
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQObjectMethodList(QDumper &d)
|
|
|
|
{
|
|
|
|
const QObject *ob = (const QObject *)d.data;
|
|
|
|
const QMetaObject *mo = ob->metaObject();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", "<synthetic>");
|
|
|
|
d.putItem("type", NS"QObjectMethodList");
|
|
|
|
d.putItem("numchild", mo->methodCount());
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-07-08 17:27:45 +02:00
|
|
|
d.putItem("childtype", "QMetaMethod::Method");
|
|
|
|
d.putItem("childnumchild", "0");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int i = 0; i != mo->methodCount(); ++i) {
|
|
|
|
const QMetaMethod & method = mo->method(i);
|
|
|
|
int mt = method.methodType();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("name");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(i).put(" ").put(mo->indexOfMethod(method.signature()));
|
|
|
|
d.put(" ").put(method.signature());
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.beginItem("value");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put((mt == QMetaMethod::Signal ? "<Signal>" : "<Slot>"));
|
|
|
|
d.put(" (").put(mt).put(")");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char * qConnectionTypes[] ={
|
|
|
|
"auto",
|
|
|
|
"direct",
|
|
|
|
"queued",
|
|
|
|
"autocompat",
|
|
|
|
"blockingqueued"
|
|
|
|
};
|
|
|
|
|
|
|
|
#if QT_VERSION >= 0x040400
|
2009-05-13 16:11:25 +02:00
|
|
|
static const ConnectionList &qConnectionList(const QObject *ob, int signalNumber)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-05-13 16:11:25 +02:00
|
|
|
static const ConnectionList emptyList;
|
2009-06-25 15:00:57 +02:00
|
|
|
const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob));
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!p->connectionLists)
|
|
|
|
return emptyList;
|
2009-05-13 16:11:25 +02:00
|
|
|
typedef QVector<ConnectionList> ConnLists;
|
2008-12-02 12:01:29 +01:00
|
|
|
const ConnLists *lists = reinterpret_cast<const ConnLists *>(p->connectionLists);
|
|
|
|
// there's an optimization making the lists only large enough to hold the
|
|
|
|
// last non-empty item
|
|
|
|
if (signalNumber >= lists->size())
|
|
|
|
return emptyList;
|
|
|
|
return lists->at(signalNumber);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-07-06 17:36:50 +02:00
|
|
|
// Write party involved in a slot/signal element,
|
|
|
|
// avoid to recursion to self.
|
|
|
|
static inline void qDumpQObjectConnectionPart(QDumper &d,
|
|
|
|
const QObject *owner,
|
|
|
|
const QObject *partner,
|
|
|
|
int number, const char *namePostfix)
|
|
|
|
{
|
|
|
|
d.beginHash();
|
|
|
|
d.beginItem("name");
|
|
|
|
d.put(number).put(namePostfix);
|
|
|
|
d.endItem();
|
|
|
|
if (partner == owner) {
|
2009-07-07 11:38:01 +02:00
|
|
|
d.putItem("value", QLatin1String("<this>"));
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", owner->metaObject()->className());
|
|
|
|
d.putItem("numchild", 0);
|
|
|
|
d.putItem("addr", owner);
|
|
|
|
} else {
|
|
|
|
qDumpInnerValueHelper(d, NS"QObject *", partner);
|
|
|
|
}
|
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
static void qDumpQObjectSignal(QDumper &d)
|
|
|
|
{
|
|
|
|
unsigned signalNumber = d.extraInt[0];
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", "<synthetic>");
|
|
|
|
d.putItem("numchild", "1");
|
|
|
|
d.putItem("type", NS"QObjectSignal");
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
#if QT_VERSION >= 0x040400
|
|
|
|
if (d.dumpChildren) {
|
|
|
|
const QObject *ob = reinterpret_cast<const QObject *>(d.data);
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-05-13 16:11:25 +02:00
|
|
|
const ConnectionList &connList = qConnectionList(ob, signalNumber);
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int i = 0; i != connList.size(); ++i) {
|
2009-05-13 16:11:25 +02:00
|
|
|
const Connection &conn = connectionAt(connList, i);
|
2009-07-06 17:36:50 +02:00
|
|
|
qDumpQObjectConnectionPart(d, ob, conn.receiver, i, " receiver");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("name");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(i).put(" slot");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", "");
|
|
|
|
if (conn.receiver)
|
|
|
|
d.putItem("value", conn.receiver->metaObject()->method(conn.method).signature());
|
2008-12-05 18:27:45 +01:00
|
|
|
else
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "<invalid receiver>");
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("name");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(i).put(" type");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", "");
|
|
|
|
d.beginItem("value");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("<").put(qConnectionTypes[conn.method]).put(" connection>");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("numchild", connList.size());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQObjectSignalList(QDumper &d)
|
|
|
|
{
|
|
|
|
const QObject *ob = reinterpret_cast<const QObject *>(d.data);
|
|
|
|
const QMetaObject *mo = ob->metaObject();
|
|
|
|
int count = 0;
|
2009-07-06 17:36:50 +02:00
|
|
|
const int methodCount = mo->methodCount();
|
|
|
|
for (int i = methodCount; --i >= 0; )
|
2008-12-02 12:01:29 +01:00
|
|
|
count += (mo->method(i).methodType() == QMetaMethod::Signal);
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("type", "QObjectSignalList");
|
|
|
|
d.putItemCount("value", count);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", d.data);
|
|
|
|
d.putItem("numchild", count);
|
2008-12-02 12:01:29 +01:00
|
|
|
#if QT_VERSION >= 0x040400
|
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-07-06 17:36:50 +02:00
|
|
|
for (int i = 0; i != methodCount; ++i) {
|
2008-12-02 12:01:29 +01:00
|
|
|
const QMetaMethod & method = mo->method(i);
|
|
|
|
if (method.methodType() == QMetaMethod::Signal) {
|
|
|
|
int k = mo->indexOfSignal(method.signature());
|
2009-05-13 16:11:25 +02:00
|
|
|
const ConnectionList &connList = qConnectionList(ob, k);
|
2008-12-02 12:01:29 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", k);
|
|
|
|
d.putItem("value", method.signature());
|
|
|
|
d.putItem("numchild", connList.size());
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("addr", d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QObjectSignal");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQObjectSlot(QDumper &d)
|
|
|
|
{
|
|
|
|
int slotNumber = d.extraInt[0];
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", d.data);
|
|
|
|
d.putItem("numchild", "1");
|
|
|
|
d.putItem("type", NS"QObjectSlot");
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
#if QT_VERSION >= 0x040400
|
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
int numchild = 0;
|
|
|
|
const QObject *ob = reinterpret_cast<const QObject *>(d.data);
|
2009-06-25 15:00:57 +02:00
|
|
|
const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob));
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int s = 0; s != p->senders.size(); ++s) {
|
2009-05-13 16:11:25 +02:00
|
|
|
const QObject *sender = senderAt(p->senders, s);
|
|
|
|
int signal = signalAt(p->senders, s);
|
|
|
|
const ConnectionList &connList = qConnectionList(sender, signal);
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int i = 0; i != connList.size(); ++i) {
|
2009-05-13 16:11:25 +02:00
|
|
|
const Connection &conn = connectionAt(connList, i);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (conn.receiver == ob && conn.method == slotNumber) {
|
|
|
|
++numchild;
|
2009-05-13 16:11:25 +02:00
|
|
|
const QMetaMethod &method = sender->metaObject()->method(signal);
|
2009-07-06 17:36:50 +02:00
|
|
|
qDumpQObjectConnectionPart(d, ob, sender, s, " sender");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("name");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(s).put(" signal");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", "");
|
|
|
|
d.putItem("value", method.signature());
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("name");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put(s).put(" type");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("type", "");
|
|
|
|
d.beginItem("value");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("<").put(qConnectionTypes[conn.method]);
|
|
|
|
d.put(" connection>");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("numchild", numchild);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQObjectSlotList(QDumper &d)
|
|
|
|
{
|
|
|
|
const QObject *ob = reinterpret_cast<const QObject *>(d.data);
|
|
|
|
#if QT_VERSION >= 0x040400
|
2009-06-25 15:00:57 +02:00
|
|
|
const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob));
|
2008-12-02 12:01:29 +01:00
|
|
|
#endif
|
|
|
|
const QMetaObject *mo = ob->metaObject();
|
|
|
|
|
|
|
|
int count = 0;
|
2009-07-06 17:36:50 +02:00
|
|
|
const int methodCount = mo->methodCount();
|
|
|
|
for (int i = methodCount; --i >= 0; )
|
2008-12-02 12:01:29 +01:00
|
|
|
count += (mo->method(i).methodType() == QMetaMethod::Slot);
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("numchild", count);
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItemCount("value", count);
|
|
|
|
d.putItem("type", NS"QObjectSlotList");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-25 15:00:57 +02:00
|
|
|
#if QT_VERSION >= 0x040400
|
2009-07-06 17:36:50 +02:00
|
|
|
for (int i = 0; i != methodCount; ++i) {
|
2008-12-02 12:01:29 +01:00
|
|
|
const QMetaMethod & method = mo->method(i);
|
|
|
|
if (method.methodType() == QMetaMethod::Slot) {
|
|
|
|
d.beginHash();
|
|
|
|
int k = mo->indexOfSlot(method.signature());
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", k);
|
|
|
|
d.putItem("value", method.signature());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
// count senders. expensive...
|
|
|
|
int numchild = 0;
|
|
|
|
for (int s = 0; s != p->senders.size(); ++s) {
|
2009-05-13 16:11:25 +02:00
|
|
|
const QObject *sender = senderAt(p->senders, s);
|
|
|
|
int signal = signalAt(p->senders, s);
|
|
|
|
const ConnectionList &connList = qConnectionList(sender, signal);
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int c = 0; c != connList.size(); ++c) {
|
2009-05-13 16:11:25 +02:00
|
|
|
const Connection &conn = connectionAt(connList, c);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (conn.receiver == ob && conn.method == k)
|
|
|
|
++numchild;
|
|
|
|
}
|
|
|
|
}
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("numchild", numchild);
|
2009-07-06 17:36:50 +02:00
|
|
|
d.putItem("addr", d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QObjectSlot");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
}
|
2009-06-25 15:00:57 +02:00
|
|
|
#endif
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-07-06 17:36:50 +02:00
|
|
|
static void qDumpQObjectChildList(QDumper &d)
|
|
|
|
{
|
|
|
|
const QObject *ob = reinterpret_cast<const QObject *>(d.data);
|
|
|
|
const QObjectList children = ob->children();
|
|
|
|
const int size = children.size();
|
|
|
|
|
|
|
|
d.putItem("numchild", size);
|
|
|
|
d.putItemCount("value", size);
|
|
|
|
d.putItem("type", NS"QObjectChildList");
|
|
|
|
if (d.dumpChildren) {
|
|
|
|
d.beginChildren();
|
|
|
|
for (int i = 0; i != size; ++i) {
|
|
|
|
d.beginHash();
|
|
|
|
d.putItem("name", i);
|
|
|
|
qDumpInnerValueHelper(d, NS"QObject *", children.at(i));
|
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
d.endChildren();
|
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-18 13:22:58 +02:00
|
|
|
#if USE_QT_GUI
|
2008-12-02 12:01:29 +01:00
|
|
|
static void qDumpQPixmap(QDumper &d)
|
|
|
|
{
|
|
|
|
const QPixmap &im = *reinterpret_cast<const QPixmap *>(d.data);
|
2009-07-01 12:49:41 +02:00
|
|
|
d.beginItem("value");
|
|
|
|
d.put("(").put(im.width()).put("x").put(im.height()).put(")");
|
|
|
|
d.endItem();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", NS"QPixmap");
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.disarm();
|
|
|
|
}
|
2009-06-18 13:22:58 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQSet(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
// This uses the knowledge that QHash<T> has only a single member
|
|
|
|
// of union { QHashData *d; QHashNode<Key, T> *e; };
|
|
|
|
QHashData *hd = *(QHashData**)d.data;
|
|
|
|
QHashData::Node *node = hd->firstNode();
|
|
|
|
|
|
|
|
int n = hd->size;
|
|
|
|
if (n < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (n > 0) {
|
|
|
|
qCheckAccess(node);
|
|
|
|
qCheckPointer(node->next);
|
|
|
|
}
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", 2 * n);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
if (n > 100)
|
|
|
|
n = 100;
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
int i = 0;
|
2008-12-08 10:25:39 +01:00
|
|
|
for (int bucket = 0; bucket != hd->numBuckets && i <= 10000; ++bucket) {
|
2008-12-02 12:01:29 +01:00
|
|
|
for (node = hd->buckets[bucket]; node->next; node = node->next) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
|
|
|
d.putItem("type", d.innertype);
|
|
|
|
d.beginItem("exp");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("(('"NS"QHashNode<").put(d.innertype
|
|
|
|
).put(","NS"QHashDummyValue>'*)"
|
|
|
|
).put(static_cast<const void*>(node)).put(")->key");
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
++i;
|
2008-12-08 10:25:39 +01:00
|
|
|
if (i > 10000) {
|
2008-12-10 16:31:50 +01:00
|
|
|
d.putEllipsis();
|
2008-12-08 10:25:39 +01:00
|
|
|
break;
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-06-25 15:00:57 +02:00
|
|
|
#if QT_VERSION >= 0x040500
|
2009-04-28 10:58:55 +02:00
|
|
|
static void qDumpQSharedPointer(QDumper &d)
|
|
|
|
{
|
|
|
|
const QSharedPointer<int> &ptr =
|
|
|
|
*reinterpret_cast<const QSharedPointer<int> *>(d.data);
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
if (isSimpleType(d.innertype))
|
2009-04-28 10:58:55 +02:00
|
|
|
qDumpInnerValueHelper(d, d.innertype, ptr.data());
|
|
|
|
else
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "");
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", 1);
|
2009-04-28 10:58:55 +02:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-04-28 10:58:55 +02:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "data");
|
2009-04-28 10:58:55 +02:00
|
|
|
qDumpInnerValue(d, d.innertype, ptr.data());
|
|
|
|
d.endHash();
|
2009-04-29 15:09:08 +02:00
|
|
|
const int v = sizeof(void *);
|
|
|
|
d.beginHash();
|
|
|
|
const void *weak = addOffset(deref(addOffset(d.data, v)), v);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "weakref");
|
|
|
|
d.putItem("value", *static_cast<const int *>(weak));
|
|
|
|
d.putItem("type", "int");
|
|
|
|
d.putItem("addr", weak);
|
|
|
|
d.putItem("numchild", "0");
|
2009-04-29 15:09:08 +02:00
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
|
|
|
const void *strong = addOffset(weak, sizeof(int));
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "strongref");
|
|
|
|
d.putItem("value", *static_cast<const int *>(strong));
|
|
|
|
d.putItem("type", "int");
|
|
|
|
d.putItem("addr", strong);
|
|
|
|
d.putItem("numchild", "0");
|
2009-04-29 15:09:08 +02:00
|
|
|
d.endHash();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-04-28 10:58:55 +02:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
2009-06-25 15:00:57 +02:00
|
|
|
#endif // QT_VERSION >= 0x040500
|
2009-04-28 10:58:55 +02:00
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQString(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
const QString &str = *reinterpret_cast<const QString *>(d.data);
|
|
|
|
|
2009-05-20 16:59:40 +02:00
|
|
|
const int size = str.size();
|
|
|
|
if (size < 0)
|
|
|
|
return;
|
|
|
|
if (size) {
|
|
|
|
const QChar *unicode = str.unicode();
|
|
|
|
qCheckAccess(unicode);
|
|
|
|
qCheckAccess(unicode + size);
|
|
|
|
if (!unicode[size].isNull()) // must be '\0' terminated
|
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", str);
|
|
|
|
d.putItem("valueencoded", "2");
|
|
|
|
d.putItem("type", NS"QString");
|
|
|
|
//d.putItem("editvalue", str); // handled generically below
|
|
|
|
d.putItem("numchild", "0");
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQStringList(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
const QStringList &list = *reinterpret_cast<const QStringList *>(d.data);
|
|
|
|
int n = list.size();
|
|
|
|
if (n < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (n > 0) {
|
|
|
|
qCheckAccess(&list.front());
|
|
|
|
qCheckAccess(&list.back());
|
|
|
|
}
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", n);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
if (n > 1000)
|
|
|
|
n = 1000;
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(n ? NS"QString" : 0);
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int i = 0; i != n; ++i) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
|
|
|
d.putItem("value", list[i]);
|
|
|
|
d.putItem("valueencoded", "2");
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
2008-12-10 16:31:50 +01:00
|
|
|
if (n < list.size())
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qDumpQTextCodec(QDumper &d)
|
|
|
|
{
|
|
|
|
const QTextCodec &codec = *reinterpret_cast<const QTextCodec *>(d.data);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", codec.name());
|
|
|
|
d.putItem("valueencoded", "1");
|
|
|
|
d.putItem("type", NS"QTextCodec");
|
|
|
|
d.putItem("numchild", "2");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putHash("name", codec.name());
|
|
|
|
d.putHash("mibEnum", codec.mibEnum());
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpQVector(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
QVectorData *v = *reinterpret_cast<QVectorData *const*>(d.data);
|
|
|
|
|
|
|
|
// Try to provoke segfaults early to prevent the frontend
|
|
|
|
// from asking for unavailable child details
|
|
|
|
int nn = v->size;
|
|
|
|
if (nn < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (nn > 0) {
|
|
|
|
//qCheckAccess(&vec.front());
|
|
|
|
//qCheckAccess(&vec.back());
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned innersize = d.extraInt[0];
|
|
|
|
unsigned typeddatasize = d.extraInt[1];
|
|
|
|
|
|
|
|
int n = nn;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", n);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
2008-12-10 16:31:50 +01:00
|
|
|
const char *stripped =
|
|
|
|
isPointerType(d.innertype) ? strippedInnerType.data() : 0;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (n > 1000)
|
|
|
|
n = 1000;
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(d.innertype);
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int i = 0; i != n; ++i) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueOrPointer(d, d.innertype, stripped,
|
2008-12-10 16:31:50 +01:00
|
|
|
addOffset(v, i * innersize + typeddatasize));
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
2008-12-10 16:31:50 +01:00
|
|
|
if (n < nn)
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-06-25 15:00:57 +02:00
|
|
|
#if QT_VERSION >= 0x040500
|
2009-04-29 17:46:37 +02:00
|
|
|
static void qDumpQWeakPointer(QDumper &d)
|
|
|
|
{
|
|
|
|
const int v = sizeof(void *);
|
|
|
|
const void *value = deref(addOffset(d.data, v));
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
if (isSimpleType(d.innertype))
|
2009-04-29 17:46:37 +02:00
|
|
|
qDumpInnerValueHelper(d, d.innertype, value);
|
|
|
|
else
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "");
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", 1);
|
2009-04-29 17:46:37 +02:00
|
|
|
if (d.dumpChildren) {
|
2009-06-26 11:32:51 +02:00
|
|
|
d.beginChildren();
|
2009-04-29 17:46:37 +02:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "data");
|
2009-04-29 17:46:37 +02:00
|
|
|
qDumpInnerValue(d, d.innertype, value);
|
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
|
|
|
const void *weak = addOffset(deref(d.data), v);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "weakref");
|
|
|
|
d.putItem("value", *static_cast<const int *>(weak));
|
|
|
|
d.putItem("type", "int");
|
|
|
|
d.putItem("addr", weak);
|
|
|
|
d.putItem("numchild", "0");
|
2009-04-29 17:46:37 +02:00
|
|
|
d.endHash();
|
|
|
|
d.beginHash();
|
|
|
|
const void *strong = addOffset(weak, sizeof(int));
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", "strongref");
|
|
|
|
d.putItem("value", *static_cast<const int *>(strong));
|
|
|
|
d.putItem("type", "int");
|
|
|
|
d.putItem("addr", strong);
|
|
|
|
d.putItem("numchild", "0");
|
2009-04-29 17:46:37 +02:00
|
|
|
d.endHash();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-04-29 17:46:37 +02:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
2009-06-25 15:00:57 +02:00
|
|
|
#endif // QT_VERSION >= 0x040500
|
2009-04-29 17:46:37 +02:00
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpStdList(QDumper &d)
|
2008-12-10 14:37:15 +01:00
|
|
|
{
|
|
|
|
const std::list<int> &list = *reinterpret_cast<const std::list<int> *>(d.data);
|
2009-05-06 09:22:05 +02:00
|
|
|
#ifdef Q_CC_MSVC
|
|
|
|
const int size = static_cast<int>(list.size());
|
|
|
|
if (size < 0)
|
|
|
|
return;
|
|
|
|
if (size)
|
|
|
|
qCheckAccess(list.begin().operator ->());
|
|
|
|
#else
|
2009-06-26 10:50:58 +02:00
|
|
|
const void *p = d.data;
|
2008-12-10 14:37:15 +01:00
|
|
|
qCheckAccess(p);
|
|
|
|
p = deref(p);
|
|
|
|
qCheckAccess(p);
|
|
|
|
p = deref(p);
|
|
|
|
qCheckAccess(p);
|
|
|
|
p = deref(addOffset(d.data, sizeof(void*)));
|
|
|
|
qCheckAccess(p);
|
|
|
|
p = deref(addOffset(p, sizeof(void*)));
|
|
|
|
qCheckAccess(p);
|
|
|
|
p = deref(addOffset(p, sizeof(void*)));
|
|
|
|
qCheckAccess(p);
|
2009-05-06 09:22:05 +02:00
|
|
|
#endif
|
2008-12-10 14:37:15 +01:00
|
|
|
int nn = 0;
|
|
|
|
std::list<int>::const_iterator it = list.begin();
|
2009-07-06 17:36:50 +02:00
|
|
|
const std::list<int>::const_iterator cend = list.end();
|
|
|
|
for (; nn < 101 && it != cend; ++nn, ++it)
|
2008-12-10 14:37:15 +01:00
|
|
|
qCheckAccess(it.operator->());
|
|
|
|
|
|
|
|
if (nn > 100)
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("value", "<more than 100 items>");
|
2008-12-10 14:37:15 +01:00
|
|
|
else
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", nn);
|
|
|
|
d.putItem("numchild", nn);
|
2008-12-10 14:37:15 +01:00
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("valuedisabled", "true");
|
2008-12-10 14:37:15 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
2008-12-10 16:31:50 +01:00
|
|
|
const char *stripped =
|
|
|
|
isPointerType(d.innertype) ? strippedInnerType.data() : 0;
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(d.innertype);
|
2008-12-10 16:48:12 +01:00
|
|
|
it = list.begin();
|
2009-07-06 17:36:50 +02:00
|
|
|
for (int i = 0; i < 1000 && it != cend; ++i, ++it) {
|
2008-12-10 14:37:15 +01:00
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueOrPointer(d, d.innertype, stripped, it.operator->());
|
2008-12-10 14:37:15 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
2008-12-10 16:31:50 +01:00
|
|
|
if (it != list.end())
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-10 14:37:15 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
/* Dump out an arbitrary map. To iterate the map,
|
|
|
|
* it is cast to a map of <KeyType,Value>. 'int' can be used for both
|
|
|
|
* for all types if the implementation does not depend on the types
|
|
|
|
* which is the case for GNU STL. The implementation used by MS VC, however,
|
|
|
|
* does depend on the key/value type, so, special cases need to be hardcoded. */
|
|
|
|
|
|
|
|
template <class KeyType, class ValueType>
|
|
|
|
static void qDumpStdMapHelper(QDumper &d)
|
2008-12-12 12:55:05 +01:00
|
|
|
{
|
2009-07-07 16:00:45 +02:00
|
|
|
typedef std::map<KeyType, ValueType> DummyType;
|
2008-12-12 13:02:29 +01:00
|
|
|
const DummyType &map = *reinterpret_cast<const DummyType*>(d.data);
|
2008-12-12 12:55:05 +01:00
|
|
|
const char *keyType = d.templateParameters[0];
|
|
|
|
const char *valueType = d.templateParameters[1];
|
|
|
|
const void *p = d.data;
|
|
|
|
qCheckAccess(p);
|
|
|
|
p = deref(p);
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
const int nn = map.size();
|
2009-04-29 14:15:09 +02:00
|
|
|
if (nn < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2009-07-07 16:00:45 +02:00
|
|
|
Q_TYPENAME DummyType::const_iterator it = map.begin();
|
|
|
|
const Q_TYPENAME DummyType::const_iterator cend = map.end();
|
|
|
|
for (int i = 0; i < nn && i < 10 && it != cend; ++i, ++it)
|
2008-12-12 12:55:05 +01:00
|
|
|
qCheckAccess(it.operator->());
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
const QByteArray strippedInnerType = stripPointerType(d.innertype);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("numchild", nn);
|
|
|
|
d.putItemCount("value", nn);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("valueoffset", d.extraInt[2]);
|
2008-12-12 12:55:05 +01:00
|
|
|
|
2008-12-17 15:46:27 +01:00
|
|
|
// HACK: we need a properly const qualified version of the
|
|
|
|
// std::pair used. We extract it from the allocator parameter
|
2008-12-17 17:43:01 +01:00
|
|
|
// (#4, "std::allocator<std::pair<key, value> >")
|
2008-12-17 15:46:27 +01:00
|
|
|
// as it is there, and, equally importantly, in an order that
|
|
|
|
// gdb accepts when fed with it.
|
2009-01-28 17:34:23 +01:00
|
|
|
char *pairType = (char *)(d.templateParameters[3]) + 15;
|
2008-12-17 15:46:27 +01:00
|
|
|
pairType[strlen(pairType) - 2] = 0;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("pairtype", pairType);
|
|
|
|
|
2008-12-12 12:55:05 +01:00
|
|
|
if (d.dumpChildren) {
|
2009-01-28 16:55:09 +01:00
|
|
|
bool isSimpleKey = isSimpleType(keyType);
|
2009-01-28 17:34:23 +01:00
|
|
|
bool isSimpleValue = isSimpleType(valueType);
|
2008-12-12 12:55:05 +01:00
|
|
|
int valueOffset = d.extraInt[2];
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("extra");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("isSimpleKey: ").put(isSimpleKey);
|
|
|
|
d.put(" isSimpleValue: ").put(isSimpleValue);
|
|
|
|
d.put(" valueType: '").put(valueType);
|
|
|
|
d.put(" valueOffset: ").put(valueOffset);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2009-01-28 17:34:23 +01:00
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(d.innertype);
|
2008-12-12 13:02:29 +01:00
|
|
|
it = map.begin();
|
2009-07-07 16:00:45 +02:00
|
|
|
for (int i = 0; i < 1000 && it != cend; ++i, ++it) {
|
2009-01-28 17:34:23 +01:00
|
|
|
d.beginHash();
|
|
|
|
const void *node = it.operator->();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2009-01-28 16:55:09 +01:00
|
|
|
qDumpInnerValueHelper(d, keyType, node, "key");
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueHelper(d, valueType, addOffset(node, valueOffset));
|
2009-01-28 17:34:23 +01:00
|
|
|
if (isSimpleKey && isSimpleValue) {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("type", valueType);
|
|
|
|
d.putItem("addr", addOffset(node, valueOffset));
|
|
|
|
d.putItem("numchild", 0);
|
2009-01-28 17:34:23 +01:00
|
|
|
} else {
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", node);
|
|
|
|
d.putItem("type", pairType);
|
|
|
|
d.putItem("numchild", 2);
|
2009-01-28 17:34:23 +01:00
|
|
|
}
|
|
|
|
d.endHash();
|
2008-12-12 12:55:05 +01:00
|
|
|
}
|
|
|
|
if (it != map.end())
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-12 12:55:05 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
static void qDumpStdMap(QDumper &d)
|
|
|
|
{
|
|
|
|
#ifdef Q_CC_MSVC
|
|
|
|
// As the map implementation inherits from a base class
|
|
|
|
// depending on the key, use something equivalent to iterate it.
|
|
|
|
const int keySize = d.extraInt[0];
|
|
|
|
const int valueSize = d.extraInt[1];
|
|
|
|
if (keySize == valueSize) {
|
|
|
|
if (keySize == sizeof(int)) {
|
|
|
|
qDumpStdMapHelper<int,int>(d);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (keySize == sizeof(std::string)) {
|
|
|
|
qDumpStdMapHelper<std::string,std::string>(d);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (keySize == sizeof(int) && valueSize == sizeof(std::string)) {
|
|
|
|
qDumpStdMapHelper<int,std::string>(d);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (keySize == sizeof(std::string) && valueSize == sizeof(int)) {
|
|
|
|
qDumpStdMapHelper<std::string,int>(d);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
qDumpStdMapHelper<int,int>(d);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Dump out an arbitrary set. To iterate the set,
|
|
|
|
* it is cast to a set of <KeyType>. 'int' can be used
|
|
|
|
* for all types if the implementation does not depend on the key type
|
|
|
|
* which is the case for GNU STL. The implementation used by MS VC, however,
|
|
|
|
* does depend on the key type, so, special cases need to be hardcoded. */
|
|
|
|
|
|
|
|
template <class KeyType>
|
|
|
|
static void qDumpStdSetHelper(QDumper &d)
|
2009-03-11 13:31:38 +01:00
|
|
|
{
|
2009-07-07 16:00:45 +02:00
|
|
|
typedef std::set<KeyType> DummyType;
|
2009-03-11 13:31:38 +01:00
|
|
|
const DummyType &set = *reinterpret_cast<const DummyType*>(d.data);
|
|
|
|
const void *p = d.data;
|
|
|
|
qCheckAccess(p);
|
|
|
|
p = deref(p);
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
const int nn = set.size();
|
2009-04-29 14:15:09 +02:00
|
|
|
if (nn < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2009-07-07 16:00:45 +02:00
|
|
|
Q_TYPENAME DummyType::const_iterator it = set.begin();
|
|
|
|
const Q_TYPENAME DummyType::const_iterator cend = set.end();
|
2009-07-06 17:36:50 +02:00
|
|
|
for (int i = 0; i < nn && i < 10 && it != cend; ++i, ++it)
|
2009-03-11 13:31:38 +01:00
|
|
|
qCheckAccess(it.operator->());
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", nn);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", nn);
|
|
|
|
d.putItem("valueoffset", d.extraInt[0]);
|
|
|
|
|
2009-03-11 13:31:38 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
int valueOffset = 0; // d.extraInt[0];
|
|
|
|
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
|
|
|
const char *stripped =
|
|
|
|
isPointerType(d.innertype) ? strippedInnerType.data() : 0;
|
|
|
|
|
2009-06-26 10:50:58 +02:00
|
|
|
d.beginItem("extra");
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("valueOffset: ").put(valueOffset);
|
2009-06-26 10:50:58 +02:00
|
|
|
d.endItem();
|
2009-03-11 13:31:38 +01:00
|
|
|
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(d.innertype);
|
2009-03-11 13:31:38 +01:00
|
|
|
it = set.begin();
|
2009-07-06 17:36:50 +02:00
|
|
|
for (int i = 0; i < 1000 && it != cend; ++i, ++it) {
|
2009-03-11 13:31:38 +01:00
|
|
|
const void *node = it.operator->();
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpInnerValueOrPointer(d, d.innertype, stripped, node);
|
2009-03-11 13:31:38 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
|
|
|
if (it != set.end())
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2009-03-11 13:31:38 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
static void qDumpStdSet(QDumper &d)
|
|
|
|
{
|
|
|
|
#ifdef Q_CC_MSVC
|
|
|
|
// As the set implementation inherits from a base class
|
|
|
|
// depending on the key, use something equivalent to iterate it.
|
|
|
|
const int innerSize = d.extraInt[0];
|
|
|
|
if (innerSize == sizeof(int)) {
|
|
|
|
qDumpStdSetHelper<int>(d);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (innerSize == sizeof(std::string)) {
|
|
|
|
qDumpStdSetHelper<std::string>(d);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (innerSize == sizeof(std::wstring)) {
|
|
|
|
qDumpStdSetHelper<std::wstring>(d);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
qDumpStdSetHelper<int>(d);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpStdString(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
const std::string &str = *reinterpret_cast<const std::string *>(d.data);
|
|
|
|
|
2009-07-03 13:56:27 +02:00
|
|
|
const std::string::size_type size = str.size();
|
|
|
|
if (int(size) < 0)
|
|
|
|
return;
|
|
|
|
if (size) {
|
2008-12-02 12:01:29 +01:00
|
|
|
qCheckAccess(str.c_str());
|
2009-07-03 13:56:27 +02:00
|
|
|
qCheckAccess(str.c_str() + size - 1);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpStdStringValue(d, str);
|
2008-12-02 12:01:29 +01:00
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpStdWString(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
const std::wstring &str = *reinterpret_cast<const std::wstring *>(d.data);
|
2009-07-03 13:56:27 +02:00
|
|
|
const std::wstring::size_type size = str.size();
|
|
|
|
if (int(size) < 0)
|
|
|
|
return;
|
|
|
|
if (size) {
|
2008-12-02 12:01:29 +01:00
|
|
|
qCheckAccess(str.c_str());
|
2009-07-03 13:56:27 +02:00
|
|
|
qCheckAccess(str.c_str() + size - 1);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-07-10 11:08:26 +02:00
|
|
|
qDumpStdWStringValue(d, str);
|
2008-12-02 12:01:29 +01:00
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpStdVector(QDumper &d)
|
2009-06-26 10:50:58 +02:00
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
// Correct type would be something like:
|
|
|
|
// std::_Vector_base<int,std::allocator<int, std::allocator<int> >>::_Vector_impl
|
|
|
|
struct VectorImpl {
|
|
|
|
char *start;
|
|
|
|
char *finish;
|
|
|
|
char *end_of_storage;
|
|
|
|
};
|
2009-05-06 09:22:05 +02:00
|
|
|
#ifdef Q_CC_MSVC
|
|
|
|
// Pointers are at end of the structure
|
|
|
|
const char * vcp = static_cast<const char *>(d.data);
|
|
|
|
const VectorImpl *v = reinterpret_cast<const VectorImpl *>(vcp + sizeof(std::vector<int>) - sizeof(VectorImpl));
|
|
|
|
#else
|
2008-12-02 12:01:29 +01:00
|
|
|
const VectorImpl *v = static_cast<const VectorImpl *>(d.data);
|
2009-05-06 09:22:05 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
// Try to provoke segfaults early to prevent the frontend
|
|
|
|
// from asking for unavailable child details
|
|
|
|
int nn = (v->finish - v->start) / d.extraInt[0];
|
|
|
|
if (nn < 0)
|
2009-04-29 14:31:11 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (nn > 0) {
|
|
|
|
qCheckAccess(v->start);
|
|
|
|
qCheckAccess(v->finish);
|
|
|
|
qCheckAccess(v->end_of_storage);
|
|
|
|
}
|
|
|
|
|
|
|
|
int n = nn;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItemCount("value", n);
|
|
|
|
d.putItem("valuedisabled", "true");
|
|
|
|
d.putItem("numchild", n);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (d.dumpChildren) {
|
|
|
|
unsigned innersize = d.extraInt[0];
|
|
|
|
QByteArray strippedInnerType = stripPointerType(d.innertype);
|
2008-12-10 16:31:50 +01:00
|
|
|
const char *stripped =
|
|
|
|
isPointerType(d.innertype) ? strippedInnerType.data() : 0;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (n > 1000)
|
|
|
|
n = 1000;
|
2009-07-10 11:08:26 +02:00
|
|
|
d.beginChildren(n ? d.innertype : 0);
|
2008-12-02 12:01:29 +01:00
|
|
|
for (int i = 0; i != n; ++i) {
|
|
|
|
d.beginHash();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("name", i);
|
2008-12-10 16:31:50 +01:00
|
|
|
qDumpInnerValueOrPointer(d, d.innertype, stripped,
|
|
|
|
addOffset(v->start, i * innersize));
|
2008-12-02 12:01:29 +01:00
|
|
|
d.endHash();
|
|
|
|
}
|
2008-12-10 16:31:50 +01:00
|
|
|
if (n < nn)
|
|
|
|
d.putEllipsis();
|
2009-06-26 11:32:51 +02:00
|
|
|
d.endChildren();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
2009-04-29 14:31:11 +02:00
|
|
|
static void qDumpStdVectorBool(QDumper &d)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
// FIXME
|
|
|
|
return qDumpStdVector(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handleProtocolVersion2and3(QDumper & d)
|
|
|
|
{
|
|
|
|
if (!d.outertype[0]) {
|
|
|
|
qDumpUnknown(d);
|
|
|
|
return;
|
|
|
|
}
|
2009-04-29 14:15:09 +02:00
|
|
|
#ifdef Q_CC_MSVC // Catch exceptions with MSVC/CDB
|
|
|
|
__try {
|
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
d.setupTemplateParameters();
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("iname", d.iname);
|
2009-06-03 12:46:55 +02:00
|
|
|
if (d.data)
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("addr", d.data);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
#ifdef QT_NO_QDATASTREAM
|
|
|
|
if (d.protocolVersion == 3) {
|
|
|
|
QVariant::Type type = QVariant::nameToType(d.outertype);
|
|
|
|
if (type != QVariant::Invalid) {
|
|
|
|
QVariant v(type, d.data);
|
|
|
|
QByteArray ba;
|
|
|
|
QDataStream ds(&ba, QIODevice::WriteOnly);
|
|
|
|
ds << v;
|
2009-06-26 10:50:58 +02:00
|
|
|
d.putItem("editvalue", ba);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
const char *type = stripNamespace(d.outertype);
|
|
|
|
// type[0] is usally 'Q', so don't use it
|
|
|
|
switch (type[1]) {
|
2009-04-09 13:47:54 +02:00
|
|
|
case 'a':
|
|
|
|
if (isEqual(type, "map"))
|
|
|
|
qDumpStdMap(d);
|
|
|
|
break;
|
2009-06-03 12:46:55 +02:00
|
|
|
case 'A':
|
|
|
|
if (isEqual(type, "QAbstractItemModel"))
|
|
|
|
qDumpQAbstractItemModel(d);
|
|
|
|
else if (isEqual(type, "QAbstractItem"))
|
|
|
|
qDumpQAbstractItem(d);
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'B':
|
|
|
|
if (isEqual(type, "QByteArray"))
|
|
|
|
qDumpQByteArray(d);
|
|
|
|
break;
|
2009-06-24 14:35:53 +02:00
|
|
|
case 'C':
|
|
|
|
if (isEqual(type, "QChar"))
|
|
|
|
qDumpQChar(d);
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'D':
|
|
|
|
if (isEqual(type, "QDateTime"))
|
|
|
|
qDumpQDateTime(d);
|
|
|
|
else if (isEqual(type, "QDir"))
|
|
|
|
qDumpQDir(d);
|
|
|
|
break;
|
2009-04-09 13:47:54 +02:00
|
|
|
case 'e':
|
|
|
|
if (isEqual(type, "vector"))
|
|
|
|
qDumpStdVector(d);
|
|
|
|
else if (isEqual(type, "set"))
|
|
|
|
qDumpStdSet(d);
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'F':
|
|
|
|
if (isEqual(type, "QFile"))
|
|
|
|
qDumpQFile(d);
|
|
|
|
else if (isEqual(type, "QFileInfo"))
|
|
|
|
qDumpQFileInfo(d);
|
|
|
|
break;
|
|
|
|
case 'H':
|
|
|
|
if (isEqual(type, "QHash"))
|
|
|
|
qDumpQHash(d);
|
|
|
|
else if (isEqual(type, "QHashNode"))
|
|
|
|
qDumpQHashNode(d);
|
|
|
|
break;
|
2009-04-09 13:47:54 +02:00
|
|
|
case 'i':
|
|
|
|
if (isEqual(type, "list"))
|
|
|
|
qDumpStdList(d);
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
case 'I':
|
2009-06-18 13:22:58 +02:00
|
|
|
#if USE_QT_GUI
|
2008-12-02 12:01:29 +01:00
|
|
|
if (isEqual(type, "QImage"))
|
|
|
|
qDumpQImage(d);
|
2009-05-29 16:24:46 +02:00
|
|
|
else if (isEqual(type, "QImageData"))
|
|
|
|
qDumpQImageData(d);
|
2009-06-18 13:22:58 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
case 'L':
|
|
|
|
if (isEqual(type, "QList"))
|
|
|
|
qDumpQList(d);
|
2009-01-08 11:50:20 +01:00
|
|
|
else if (isEqual(type, "QLinkedList"))
|
|
|
|
qDumpQLinkedList(d);
|
2008-12-02 12:01:29 +01:00
|
|
|
else if (isEqual(type, "QLocale"))
|
|
|
|
qDumpQLocale(d);
|
|
|
|
break;
|
|
|
|
case 'M':
|
|
|
|
if (isEqual(type, "QMap"))
|
|
|
|
qDumpQMap(d);
|
|
|
|
else if (isEqual(type, "QMapNode"))
|
|
|
|
qDumpQMapNode(d);
|
|
|
|
else if (isEqual(type, "QModelIndex"))
|
|
|
|
qDumpQModelIndex(d);
|
2009-01-07 16:29:14 +01:00
|
|
|
else if (isEqual(type, "QMultiMap"))
|
2009-01-08 11:50:20 +01:00
|
|
|
qDumpQMultiMap(d);
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
case 'O':
|
|
|
|
if (isEqual(type, "QObject"))
|
|
|
|
qDumpQObject(d);
|
|
|
|
else if (isEqual(type, "QObjectPropertyList"))
|
|
|
|
qDumpQObjectPropertyList(d);
|
2009-07-06 17:36:50 +02:00
|
|
|
else if (isEqual(type, "QObjectProperty"))
|
|
|
|
qDumpQObjectProperty(d);
|
2008-12-02 12:01:29 +01:00
|
|
|
else if (isEqual(type, "QObjectMethodList"))
|
|
|
|
qDumpQObjectMethodList(d);
|
|
|
|
else if (isEqual(type, "QObjectSignal"))
|
|
|
|
qDumpQObjectSignal(d);
|
|
|
|
else if (isEqual(type, "QObjectSignalList"))
|
|
|
|
qDumpQObjectSignalList(d);
|
|
|
|
else if (isEqual(type, "QObjectSlot"))
|
|
|
|
qDumpQObjectSlot(d);
|
|
|
|
else if (isEqual(type, "QObjectSlotList"))
|
|
|
|
qDumpQObjectSlotList(d);
|
2009-07-06 17:36:50 +02:00
|
|
|
else if (isEqual(type, "QObjectChildList"))
|
|
|
|
qDumpQObjectChildList(d);
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
case 'P':
|
2009-06-18 13:22:58 +02:00
|
|
|
#if USE_QT_GUI
|
2008-12-02 12:01:29 +01:00
|
|
|
if (isEqual(type, "QPixmap"))
|
|
|
|
qDumpQPixmap(d);
|
2009-06-18 13:22:58 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
if (isEqual(type, "QSet"))
|
|
|
|
qDumpQSet(d);
|
2009-06-25 15:00:57 +02:00
|
|
|
#if QT_VERSION >= 0x040500
|
2009-04-28 10:58:55 +02:00
|
|
|
else if (isEqual(type, "QSharedPointer"))
|
|
|
|
qDumpQSharedPointer(d);
|
2009-06-25 15:00:57 +02:00
|
|
|
#endif
|
2008-12-02 12:01:29 +01:00
|
|
|
else if (isEqual(type, "QString"))
|
|
|
|
qDumpQString(d);
|
|
|
|
else if (isEqual(type, "QStringList"))
|
|
|
|
qDumpQStringList(d);
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if (isEqual(type, "wstring"))
|
|
|
|
qDumpStdWString(d);
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (isEqual(type, "std::vector"))
|
|
|
|
qDumpStdVector(d);
|
|
|
|
else if (isEqual(type, "std::vector::bool"))
|
|
|
|
qDumpStdVectorBool(d);
|
2008-12-10 14:37:15 +01:00
|
|
|
else if (isEqual(type, "std::list"))
|
|
|
|
qDumpStdList(d);
|
2008-12-12 12:55:05 +01:00
|
|
|
else if (isEqual(type, "std::map"))
|
|
|
|
qDumpStdMap(d);
|
2009-03-11 13:31:38 +01:00
|
|
|
else if (isEqual(type, "std::set"))
|
|
|
|
qDumpStdSet(d);
|
2008-12-12 12:55:05 +01:00
|
|
|
else if (isEqual(type, "std::string") || isEqual(type, "string"))
|
2008-12-02 12:01:29 +01:00
|
|
|
qDumpStdString(d);
|
|
|
|
else if (isEqual(type, "std::wstring"))
|
|
|
|
qDumpStdWString(d);
|
|
|
|
break;
|
2009-04-29 17:46:37 +02:00
|
|
|
case 'T':
|
|
|
|
if (isEqual(type, "QTextCodec"))
|
|
|
|
qDumpQTextCodec(d);
|
|
|
|
break;
|
|
|
|
case 'V':
|
|
|
|
if (isEqual(type, "QVariant"))
|
|
|
|
qDumpQVariant(d);
|
|
|
|
else if (isEqual(type, "QVector"))
|
|
|
|
qDumpQVector(d);
|
|
|
|
break;
|
|
|
|
case 'W':
|
2009-06-25 15:00:57 +02:00
|
|
|
#if QT_VERSION >= 0x040500
|
2009-04-29 17:46:37 +02:00
|
|
|
if (isEqual(type, "QWeakPointer"))
|
|
|
|
qDumpQWeakPointer(d);
|
2009-06-25 15:00:57 +02:00
|
|
|
#endif
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!d.success)
|
|
|
|
qDumpUnknown(d);
|
2009-04-29 14:15:09 +02:00
|
|
|
#ifdef Q_CC_MSVC // Catch exceptions with MSVC/CDB
|
|
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
qDumpUnknown(d, DUMPUNKNOWN_MESSAGE" <exception>");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
2009-07-01 12:49:41 +02:00
|
|
|
#if USE_QT_GUI
|
|
|
|
extern "C" Q_DECL_EXPORT
|
|
|
|
void *watchPoint(int x, int y)
|
|
|
|
{
|
|
|
|
return QApplication::widgetAt(x, y);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-07-02 16:38:15 +02:00
|
|
|
// Helper to write out common expression values for CDB:
|
|
|
|
// Offsets of a map node value which looks like
|
|
|
|
// "(size_t)&(('QMapNode<QString,QString >'*)0)->value")" in gdb syntax
|
|
|
|
|
|
|
|
template <class Key, class Value>
|
|
|
|
inline QDumper & putQMapNodeOffsetExpression(const char *keyType,
|
|
|
|
const char *valueType,
|
|
|
|
QDumper &d)
|
|
|
|
{
|
|
|
|
QMapNode<Key, Value> *mn = 0;
|
|
|
|
const int valueOffset = (char *)&(mn->value) - (char*)mn;
|
|
|
|
d.put("(size_t)&(('"NS"QMapNode<");
|
|
|
|
d.put(keyType);
|
|
|
|
d.put(',');
|
|
|
|
d.put(valueType);
|
2009-07-07 16:00:45 +02:00
|
|
|
if (valueType[qstrlen(valueType) - 1] == '>')
|
|
|
|
d.put(' ');
|
2009-07-02 16:38:15 +02:00
|
|
|
d.put(">'*)0)->value=\"");
|
|
|
|
d.put(valueOffset);
|
|
|
|
d.put('"');
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2009-07-07 16:00:45 +02:00
|
|
|
// Helper to write out common expression values for CDB:
|
|
|
|
// Offsets of a std::pair for dumping std::map node value which look like
|
|
|
|
// "(size_t)&(('std::pair<int const ,unsigned int>'*)0)->second"
|
|
|
|
|
|
|
|
template <class Key, class Value>
|
|
|
|
inline QDumper & putStdPairValueOffsetExpression(const char *keyType,
|
|
|
|
const char *valueType,
|
|
|
|
QDumper &d)
|
|
|
|
{
|
|
|
|
std::pair<Key, Value> *p = 0;
|
|
|
|
const int valueOffset = (char *)&(p->second) - (char*)p;
|
|
|
|
d.put("(size_t)&(('std::pair<");
|
|
|
|
d.put(keyType);
|
|
|
|
d.put(" const ,");
|
|
|
|
d.put(valueType);
|
|
|
|
if (valueType[qstrlen(valueType) - 1] == '>')
|
|
|
|
d.put(' ');
|
|
|
|
d.put(">'*)0)->second=\"");
|
|
|
|
d.put(valueOffset);
|
|
|
|
d.put('"');
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
extern "C" Q_DECL_EXPORT
|
2009-04-16 08:43:00 +02:00
|
|
|
void *qDumpObjectData440(
|
2008-12-02 12:01:29 +01:00
|
|
|
int protocolVersion,
|
|
|
|
int token,
|
|
|
|
void *data,
|
2009-04-22 17:28:26 +02:00
|
|
|
int dumpChildren,
|
2008-12-02 12:01:29 +01:00
|
|
|
int extraInt0,
|
|
|
|
int extraInt1,
|
|
|
|
int extraInt2,
|
|
|
|
int extraInt3)
|
|
|
|
{
|
2009-02-11 14:17:25 +01:00
|
|
|
//sleep(20);
|
2008-12-12 13:09:34 +01:00
|
|
|
if (protocolVersion == 1) {
|
2008-12-02 12:01:29 +01:00
|
|
|
QDumper d;
|
|
|
|
d.protocolVersion = protocolVersion;
|
|
|
|
d.token = token;
|
|
|
|
|
2008-12-18 10:11:10 +01:00
|
|
|
// This is a list of all available dumpers. Note that some templates
|
|
|
|
// currently require special hardcoded handling in the debugger plugin.
|
2009-05-05 18:49:35 +02:00
|
|
|
// They are mentioned here nevertheless. For types that are not listed
|
2008-12-18 10:11:10 +01:00
|
|
|
// here, dumpers won't be used.
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("dumpers=["
|
2009-06-03 12:46:55 +02:00
|
|
|
"\""NS"QAbstractItem\","
|
|
|
|
"\""NS"QAbstractItemModel\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\""NS"QByteArray\","
|
2009-06-25 15:00:57 +02:00
|
|
|
"\""NS"QChar\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\""NS"QDateTime\","
|
|
|
|
"\""NS"QDir\","
|
|
|
|
"\""NS"QFile\","
|
|
|
|
"\""NS"QFileInfo\","
|
|
|
|
"\""NS"QHash\","
|
|
|
|
"\""NS"QHashNode\","
|
|
|
|
"\""NS"QImage\","
|
2009-05-29 16:24:46 +02:00
|
|
|
"\""NS"QImageData\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\""NS"QLinkedList\","
|
|
|
|
"\""NS"QList\","
|
|
|
|
"\""NS"QLocale\","
|
|
|
|
"\""NS"QMap\","
|
|
|
|
"\""NS"QMapNode\","
|
|
|
|
"\""NS"QModelIndex\","
|
|
|
|
"\""NS"QObject\","
|
|
|
|
"\""NS"QObjectMethodList\"," // hack to get nested properties display
|
2009-07-06 17:36:50 +02:00
|
|
|
"\""NS"QObjectProperty\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\""NS"QObjectPropertyList\","
|
|
|
|
"\""NS"QObjectSignal\","
|
|
|
|
"\""NS"QObjectSignalList\","
|
|
|
|
"\""NS"QObjectSlot\","
|
|
|
|
"\""NS"QObjectSlotList\","
|
2009-07-06 17:36:50 +02:00
|
|
|
"\""NS"QObjectChildList\","
|
2009-06-26 11:32:51 +02:00
|
|
|
//"\""NS"QRegion\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\""NS"QSet\","
|
|
|
|
"\""NS"QString\","
|
|
|
|
"\""NS"QStringList\","
|
|
|
|
"\""NS"QTextCodec\","
|
|
|
|
"\""NS"QVariant\","
|
|
|
|
"\""NS"QVector\","
|
2009-06-25 15:00:57 +02:00
|
|
|
#if QT_VERSION >= 0x040500
|
|
|
|
"\""NS"QMultiMap\","
|
|
|
|
"\""NS"QSharedPointer\","
|
2009-04-29 17:46:37 +02:00
|
|
|
"\""NS"QWeakPointer\","
|
2009-06-25 15:00:57 +02:00
|
|
|
#endif
|
2009-06-18 13:22:58 +02:00
|
|
|
#if USE_QT_GUI
|
2009-01-27 17:41:31 +01:00
|
|
|
"\""NS"QWidget\","
|
2009-06-18 13:22:58 +02:00
|
|
|
#endif
|
2009-06-26 10:50:58 +02:00
|
|
|
#ifdef Q_OS_WIN
|
2009-04-09 13:47:54 +02:00
|
|
|
"\"basic_string\","
|
|
|
|
"\"list\","
|
|
|
|
"\"map\","
|
|
|
|
"\"set\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\"string\","
|
2009-04-09 13:47:54 +02:00
|
|
|
"\"vector\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\"wstring\","
|
2009-04-09 13:47:54 +02:00
|
|
|
#endif
|
2009-01-27 17:41:31 +01:00
|
|
|
"\"std::basic_string\","
|
|
|
|
"\"std::list\","
|
|
|
|
"\"std::map\","
|
2009-03-11 13:31:38 +01:00
|
|
|
"\"std::set\","
|
2009-01-27 17:41:31 +01:00
|
|
|
"\"std::string\","
|
|
|
|
"\"std::vector\","
|
|
|
|
"\"std::wstring\","
|
2009-06-26 11:32:51 +02:00
|
|
|
"]");
|
|
|
|
d.put(",qtversion=["
|
|
|
|
"\"").put(((QT_VERSION >> 16) & 255)).put("\","
|
|
|
|
"\"").put(((QT_VERSION >> 8) & 255)).put("\","
|
|
|
|
"\"").put(((QT_VERSION) & 255)).put("\"]");
|
2009-07-06 17:36:50 +02:00
|
|
|
d.put(",dumperversion=\"1.3\",");
|
2009-04-29 16:52:14 +02:00
|
|
|
// Dump out size information
|
2009-06-26 11:32:51 +02:00
|
|
|
d.put("sizes={");
|
|
|
|
d.put("int=\"").put(sizeof(int)).put("\",")
|
|
|
|
.put("char*=\"").put(sizeof(char*)).put("\",")
|
|
|
|
.put(""NS"QString=\"").put(sizeof(QString)).put("\",")
|
|
|
|
.put(""NS"QStringList=\"").put(sizeof(QStringList)).put("\",")
|
|
|
|
.put(""NS"QObject=\"").put(sizeof(QObject)).put("\",")
|
2009-06-18 13:22:58 +02:00
|
|
|
#if USE_QT_GUI
|
2009-07-01 12:49:41 +02:00
|
|
|
.put(""NS"QWidget=\"").put(sizeof(QWidget)).put("\",")
|
2009-04-29 16:52:14 +02:00
|
|
|
#endif
|
|
|
|
#ifdef Q_OS_WIN
|
2009-06-26 11:32:51 +02:00
|
|
|
.put("string=\"").put(sizeof(std::string)).put("\",")
|
|
|
|
.put("wstring=\"").put(sizeof(std::wstring)).put("\",")
|
2009-04-29 16:52:14 +02:00
|
|
|
#endif
|
2009-06-26 11:32:51 +02:00
|
|
|
.put("std::string=\"").put(sizeof(std::string)).put("\",")
|
|
|
|
.put("std::wstring=\"").put(sizeof(std::wstring)).put("\",")
|
2009-07-02 16:38:15 +02:00
|
|
|
.put("std::allocator=\"").put(sizeof(std::allocator<int>)).put("\",")
|
2009-07-03 13:56:27 +02:00
|
|
|
.put("std::char_traits<char>=\"").put(sizeof(std::char_traits<char>)).put("\",")
|
|
|
|
.put("std::char_traits<unsigned short>=\"").put(sizeof(std::char_traits<unsigned short>)).put("\",")
|
2009-07-02 16:38:15 +02:00
|
|
|
#if QT_VERSION >= 0x040500
|
|
|
|
.put(NS"QSharedPointer=\"").put(sizeof(QSharedPointer<int>)).put("\",")
|
|
|
|
.put(NS"QSharedDataPointer=\"").put(sizeof(QSharedDataPointer<QSharedData>)).put("\",")
|
|
|
|
.put(NS"QWeakPointer=\"").put(sizeof(QWeakPointer<int>)).put("\",")
|
|
|
|
#endif
|
|
|
|
.put("QPointer=\"").put(sizeof(QPointer<QObject>)).put("\",")
|
|
|
|
// Common map node types
|
|
|
|
.put(NS"QMapNode<int,int>=\"").put(sizeof(QMapNode<int,int >)).put("\",")
|
|
|
|
.put(NS"QMapNode<int,"NS"QString>=\"").put(sizeof(QMapNode<int, QString>)).put("\",")
|
|
|
|
.put(NS"QMapNode<int,"NS"QVariant>=\"").put(sizeof(QMapNode<int, QVariant>)).put("\",")
|
|
|
|
.put(NS"QMapNode<"NS"QString,int>=\"").put(sizeof(QMapNode<QString, int>)).put("\",")
|
|
|
|
.put(NS"QMapNode<"NS"QString,"NS"QString>=\"").put(sizeof(QMapNode<QString, QString>)).put("\",")
|
|
|
|
.put(NS"QMapNode<"NS"QString,"NS"QVariant>=\"").put(sizeof(QMapNode<QString, QVariant>))
|
2009-06-26 11:32:51 +02:00
|
|
|
.put("\"}");
|
2009-07-02 16:38:15 +02:00
|
|
|
// Write out common expression values for CDB
|
|
|
|
d.put(",expressions={");
|
|
|
|
putQMapNodeOffsetExpression<int,int>("int", "int", d).put(',');
|
|
|
|
putQMapNodeOffsetExpression<int,QString>("int", NS"QString", d).put(',');
|
|
|
|
putQMapNodeOffsetExpression<int,QVariant>("int", NS"QVariant", d).put(',');
|
|
|
|
putQMapNodeOffsetExpression<QString,int>(NS"QString", "int", d).put(',');
|
|
|
|
putQMapNodeOffsetExpression<QString,QString>(NS"QString", NS"QString", d).put(',');
|
2009-07-07 16:00:45 +02:00
|
|
|
putQMapNodeOffsetExpression<QString,QVariant>(NS"QString", NS"QVariant", d).put(',');
|
|
|
|
// Std Pairs
|
|
|
|
putStdPairValueOffsetExpression<int,int>("int","int", d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<QString,QString>(NS"QString",NS"QString", d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<int,QString>("int",NS"QString", d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<QString,int>(NS"QString", "int", d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<std::string,std::string>(stdStringTypeC, stdStringTypeC, d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<int,std::string>("int", stdStringTypeC, d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<std::string,int>(stdStringTypeC, "int", d.put(','));
|
|
|
|
putStdPairValueOffsetExpression<std::wstring,std::wstring>(stdWideStringTypeUShortC, stdWideStringTypeUShortC, d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<int,std::wstring>("int", stdWideStringTypeUShortC, d).put(',');
|
|
|
|
putStdPairValueOffsetExpression<std::wstring,int>(stdWideStringTypeUShortC, "int", d);
|
2009-07-02 16:38:15 +02:00
|
|
|
d.put('}');
|
2008-12-02 12:01:29 +01:00
|
|
|
d.disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (protocolVersion == 2 || protocolVersion == 3) {
|
|
|
|
QDumper d;
|
|
|
|
|
|
|
|
d.protocolVersion = protocolVersion;
|
|
|
|
d.token = token;
|
|
|
|
d.data = data;
|
|
|
|
d.dumpChildren = dumpChildren;
|
|
|
|
d.extraInt[0] = extraInt0;
|
|
|
|
d.extraInt[1] = extraInt1;
|
|
|
|
d.extraInt[2] = extraInt2;
|
|
|
|
d.extraInt[3] = extraInt3;
|
|
|
|
|
2009-06-25 15:00:57 +02:00
|
|
|
const char *inbuffer = inBuffer;
|
2008-12-02 12:01:29 +01:00
|
|
|
d.outertype = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
|
|
|
|
d.iname = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
|
|
|
|
d.exp = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
|
|
|
|
d.innertype = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
|
2009-06-08 11:45:15 +02:00
|
|
|
d.iname = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
handleProtocolVersion2and3(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
qDebug() << "Unsupported protocol version" << protocolVersion;
|
|
|
|
}
|
2009-06-25 15:00:57 +02:00
|
|
|
return outBuffer;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|