📄 gdbmacros.cpp
字号:
//////////////////////////////////////////////////////////////////////////////
static void qDumpQByteArray(QDumper &d)
{
const QByteArray &ba = *reinterpret_cast<const QByteArray *>(d.data);
if (!ba.isEmpty()) {
qCheckAccess(ba.constData());
qCheckAccess(ba.constData() + ba.size());
}
if (ba.size() <= 100)
P(d, "value", ba);
else
P(d, "value", ba.left(100) << " <size: " << ba.size() << ", cut...>");
P(d, "valueencoded", "1");
P(d, "type", NS"QByteArray");
P(d, "numchild", ba.size());
P(d, "childtype", "char");
P(d, "childnumchild", "0");
if (d.dumpChildren) {
d << ",children=[";
char buf[20];
for (int i = 0; i != ba.size(); ++i) {
unsigned char c = ba.at(i);
unsigned char u = isprint(c) && c != '"' ? c : '?';
sprintf(buf, "%02x (%u '%c')", c, c, u);
d.beginHash();
P(d, "name", "[" << i << "]");
P(d, "value", buf);
d.endHash();
}
d << "]";
}
d.disarm();
}
static void qDumpQDateTime(QDumper &d)
{
#ifdef QT_NO_DATESTRING
qDumpUnknown(d);
#else
const QDateTime &date = *reinterpret_cast<const QDateTime *>(d.data);
if (date.isNull()) {
P(d, "value", "(null)");
} else {
P(d, "value", date.toString());
P(d, "valueencoded", "1");
}
P(d, "type", NS"QDateTime");
P(d, "numchild", "3");
if (d.dumpChildren) {
d << ",children=[";
BL(d, "isNull", date.isNull());
I(d, "toTime_t", (long)date.toTime_t());
S(d, "toString", date.toString());
S(d, "toString_(ISO)", date.toString(Qt::ISODate));
S(d, "toString_(SystemLocale)", date.toString(Qt::SystemLocaleDate));
S(d, "toString_(Locale)", date.toString(Qt::LocaleDate));
S(d, "toString", date.toString());
#if 0
d.beginHash();
P(d, "name", "toUTC");
P(d, "exp", "(("NSX"QDateTime"NSY"*)" << d.data << ")"
"->toTimeSpec('"NS"Qt::UTC')");
P(d, "type", NS"QDateTime");
P(d, "numchild", "1");
d.endHash();
#endif
#if 0
d.beginHash();
P(d, "name", "toLocalTime");
P(d, "exp", "(("NSX"QDateTime"NSY"*)" << d.data << ")"
"->toTimeSpec('"NS"Qt::LocalTime')");
P(d, "type", NS"QDateTime");
P(d, "numchild", "1");
d.endHash();
#endif
d << "]";
}
d.disarm();
#endif // ifdef QT_NO_DATESTRING
}
static void qDumpQDir(QDumper &d)
{
const QDir &dir = *reinterpret_cast<const QDir *>(d.data);
P(d, "value", dir.path());
P(d, "valueencoded", "1");
P(d, "type", NS"QDir");
P(d, "numchild", "3");
if (d.dumpChildren) {
d << ",children=[";
S(d, "absolutePath", dir.absolutePath());
S(d, "canonicalPath", dir.canonicalPath());
d << "]";
}
d.disarm();
}
static void qDumpQFile(QDumper &d)
{
const QFile &file = *reinterpret_cast<const QFile *>(d.data);
P(d, "value", file.fileName());
P(d, "valueencoded", "1");
P(d, "type", NS"QFile");
P(d, "numchild", "2");
if (d.dumpChildren) {
d << ",children=[";
S(d, "fileName", file.fileName());
BL(d, "exists", file.exists());
d << "]";
}
d.disarm();
}
static void qDumpQFileInfo(QDumper &d)
{
const QFileInfo &info = *reinterpret_cast<const QFileInfo *>(d.data);
P(d, "value", info.filePath());
P(d, "valueencoded", "1");
P(d, "type", NS"QFileInfo");
P(d, "numchild", "3");
if (d.dumpChildren) {
d << ",children=[";
S(d, "absolutePath", info.absolutePath());
S(d, "absoluteFilePath", info.absoluteFilePath());
S(d, "canonicalPath", info.canonicalPath());
S(d, "canonicalFilePath", info.canonicalFilePath());
S(d, "completeBaseName", info.completeBaseName());
S(d, "completeSuffix", info.completeSuffix());
S(d, "baseName", info.baseName());
#ifdef Q_OS_MACX
BL(d, "isBundle", info.isBundle());
S(d, "bundleName", info.bundleName());
#endif
S(d, "completeSuffix", info.completeSuffix());
S(d, "fileName", info.fileName());
S(d, "filePath", info.filePath());
S(d, "group", info.group());
S(d, "owner", info.owner());
S(d, "path", info.path());
I(d, "groupid", (long)info.groupId());
I(d, "ownerid", (long)info.ownerId());
//QFile::Permissions permissions () const
I(d, "permissions", info.permissions());
//QDir absoluteDir () const
//QDir dir () const
BL(d, "caching", info.caching());
BL(d, "exists", info.exists());
BL(d, "isAbsolute", info.isAbsolute());
BL(d, "isDir", info.isDir());
BL(d, "isExecutable", info.isExecutable());
BL(d, "isFile", info.isFile());
BL(d, "isHidden", info.isHidden());
BL(d, "isReadable", info.isReadable());
BL(d, "isRelative", info.isRelative());
BL(d, "isRoot", info.isRoot());
BL(d, "isSymLink", info.isSymLink());
BL(d, "isWritable", info.isWritable());
d.beginHash();
P(d, "name", "created");
P(d, "value", info.created().toString());
P(d, "valueencoded", "1");
P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->created()");
P(d, "type", NS"QDateTime");
P(d, "numchild", "1");
d.endHash();
d.beginHash();
P(d, "name", "lastModified");
P(d, "value", info.lastModified().toString());
P(d, "valueencoded", "1");
P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->lastModified()");
P(d, "type", NS"QDateTime");
P(d, "numchild", "1");
d.endHash();
d.beginHash();
P(d, "name", "lastRead");
P(d, "value", info.lastRead().toString());
P(d, "valueencoded", "1");
P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->lastRead()");
P(d, "type", NS"QDateTime");
P(d, "numchild", "1");
d.endHash();
d << "]";
}
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;
}
}
static void qDumpQHash(QDumper &d)
{
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)
qCheck(false);
if (n > 0) {
qCheckPointer(h->fakeNext);
qCheckPointer(*h->buckets);
}
P(d, "value", "<" << n << " items>");
P(d, "numchild", n);
if (d.dumpChildren) {
if (n > 1000)
n = 1000;
bool simpleKey = isShortKey(keyType);
bool simpleValue = isShortKey(valueType);
bool opt = isOptimizedIntKey(keyType);
int keyOffset = hashOffset(opt, true, keySize, valueSize);
int valueOffset = hashOffset(opt, false, keySize, valueSize);
P(d, "extra", "simplekey: " << simpleKey << " simpleValue: " << simpleValue
<< " keySize: " << keyOffset << " valueOffset: " << valueOffset
<< " opt: " << opt);
QHashData::Node *node = h->firstNode();
QHashData::Node *end = reinterpret_cast<QHashData::Node *>(h);
int i = 0;
d << ",children=[";
while (node != end) {
d.beginHash();
if (simpleKey) {
qDumpInnerValueHelper(d, keyType, addOffset(node, keyOffset), "name");
P(d, "nameisindex", "1");
if (simpleValue)
qDumpInnerValueHelper(d, valueType, addOffset(node, valueOffset));
P(d, "type", valueType);
P(d, "addr", addOffset(node, valueOffset));
} else {
P(d, "name", "[" << i << "]");
//P(d, "exp", "*(char*)" << node);
P(d, "exp", "*('"NS"QHashNode<" << keyType << "," << valueType << " >'*)" << node);
P(d, "type", "'"NS"QHashNode<" << keyType << "," << valueType << " >'");
}
d.endHash();
++i;
node = QHashData::nextNode(node);
}
d << "]";
}
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];
P(d, "value", "");
P(d, "numchild", 2);
if (d.dumpChildren) {
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);
// there is a hash specialization in cast the key are integers or shorts
d << ",children=[";
d.beginHash();
P(d, "name", "key");
P(d, "type", keyType);
P(d, "addr", addOffset(h, keyOffset));
d.endHash();
d.beginHash();
P(d, "name", "value");
P(d, "type", valueType);
P(d, "addr", addOffset(h, valueOffset));
d.endHash();
d << "]";
}
d.disarm();
}
static void qDumpQImage(QDumper &d)
{
#ifdef QT_GUI_LIB
const QImage &im = *reinterpret_cast<const QImage *>(d.data);
P(d, "value", "(" << im.width() << "x" << im.height() << ")");
P(d, "type", NS"QImage");
P(d, "numchild", "0");
d.disarm();
#else
Q_UNUSED(d);
#endif
}
static void qDumpQList(QDumper &d)
{
// This uses the knowledge that QList<T> has only a single member
// of type union { QListData p; QListData::Data *d; };
const QListData &ldata = *reinterpret_cast<const QListData*>(d.data);
const QListData::Data *pdata =
*reinterpret_cast<const QListData::Data* const*>(d.data);
int nn = ldata.size();
if (nn < 0)
qCheck(false);
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)
qCheck(false);
#endif
}
int n = nn;
P(d, "value", "<" << n << " items>");
P(d, "valuedisabled", "true");
P(d, "numchild", n);
P(d, "childtype", d.innertype);
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);
P(d, "internal", (int)isInternal);
P(d, "childtype", d.innertype);
if (n > 1000)
n = 1000;
d << ",children=[";
for (int i = 0; i != n; ++i) {
d.beginHash();
P(d, "name", "[" << i << "]");
if (innerTypeIsPointer) {
void *p = ldata.d->array + i + pdata->begin;
if (p) {
//P(d, "value","@" << p);
qDumpInnerValue(d, strippedInnerType.data(), deref(p));
} else {
P(d, "value", "<null>");
P(d, "numchild", "0");
}
} else {
void *p = ldata.d->array + i + pdata->begin;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -