From 94c613c9fe801da696df62ad3db56a08ee07003f Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Wed, 10 Dec 2008 14:37:15 +0100 Subject: [PATCH] add custom dumpers for std::list --- bin/gdbmacros/gdbmacros.cpp | 73 +++++++++++++++ src/plugins/debugger/gdbengine.cpp | 2 + src/plugins/debugger/watchhandler.cpp | 22 ++++- tests/manual/gdbdebugger/simple/app.cpp | 119 ++++++++++++++++-------- 4 files changed, 170 insertions(+), 46 deletions(-) diff --git a/bin/gdbmacros/gdbmacros.cpp b/bin/gdbmacros/gdbmacros.cpp index 199b783f45d..e074ddd2a5d 100644 --- a/bin/gdbmacros/gdbmacros.cpp +++ b/bin/gdbmacros/gdbmacros.cpp @@ -122,6 +122,7 @@ int qtGhVersion = QT_VERSION; # include <QImage> #endif +#include <list> #include <string> #include <vector> @@ -2101,6 +2102,76 @@ static void qDumpQVector(QDumper &d) d.disarm(); } +static void qDumpStdList(QDumper &d) +{ + const std::list<int> &list = *reinterpret_cast<const std::list<int> *>(d.data); + const void *p = d.data; + qCheckAccess(p); + p = deref(p); + 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); + p = deref(addOffset(p, sizeof(void*))); + qCheckAccess(p); + + int nn = 0; + std::list<int>::const_iterator it = list.begin(); + for (int i = 0; i < 101 && it != list.end(); ++i, ++it) { + qCheckAccess(it.operator->()); + ++nn; + } + + if (nn > 100) + P(d, "value", "<more than 100 items>"); + else + P(d, "value", "<" << nn << " items>"); + P(d, "numchild", nn); + + P(d, "valuedisabled", "true"); + if (d.dumpChildren) { + unsigned innersize = d.extraInt[0]; + bool innerTypeIsPointer = isPointerType(d.innertype); + QByteArray strippedInnerType = stripPointerType(d.innertype); + d << ",children=["; + std::list<int>::const_iterator it = list.begin(); + for (int i = 0; i < 1000 && it != list.end(); ++i, ++it) { + d.beginHash(); + P(d, "name", "[" << i << "]"); + P(d, "type", d.innertype); + const void *p = it.operator->(); + if (innerTypeIsPointer) { + if (deref(p)) { + qDumpInnerValue(d, strippedInnerType.data(), deref(p)); + } else { + P(d, "type", d.innertype); + P(d, "value", "<null>"); + P(d, "numchild", "0"); + } + } else { + qDumpInnerValue(d, d.innertype, p); + } + d.endHash(); + } + if (it != list.end()) { + d.beginHash(); + P(d, "name", "[...]"); + P(d, "value", "<incomplete>"); + P(d, "type", d.innertype); + d.endHash(); + } + d << "]"; + } + d.disarm(); +} + static void qDumpStdString(QDumper &d) { const std::string &str = *reinterpret_cast<const std::string *>(d.data); @@ -2325,6 +2396,8 @@ static void handleProtocolVersion2and3(QDumper & d) qDumpStdVector(d); else if (isEqual(type, "std::vector::bool")) qDumpStdVectorBool(d); + else if (isEqual(type, "std::list")) + qDumpStdList(d); else if (isEqual(type, "string")) qDumpStdString(d); else if (isEqual(type, "std::string")) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index d7ac5b1aaa1..83473674782 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -2939,6 +2939,8 @@ bool GdbEngine::isCustomValueDumperAvailable(const QString &type) const if (tmplate == "QSet") return true; } + if (tmplate == "std::list") + return true; if (tmplate == "std::vector" && inner != "bool") return true; if (tmplate == "std::basic_string") { diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 053fcadcd19..47f1593db36 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -402,18 +402,30 @@ bool WatchHandler::setData(const QModelIndex &idx, static QString niceType(QString type) { if (type.contains("std::")) { - static QRegExp re("std::vector<(.*)\\s*,std::allocator<(.*)>\\s*>"); - re.setMinimal(true); - + // std::string type.replace("std::basic_string<char, std::char_traits<char>, " "std::allocator<char> >", "std::string"); + + // std::wstring type.replace("std::basic_string<wchar_t, std::char_traits<wchar_t>, " "std::allocator<wchar_t> >", "std::wstring"); + // std::vector + static QRegExp re1("std::vector<(.*)\\s*,std::allocator<(.*)>\\s*>"); + re1.setMinimal(true); + for (int i = 0; i != 10; ++i) { + if (re1.indexIn(type) == -1 || re1.cap(1) != re1.cap(2)) + break; + type.replace(re1.cap(0), "std::vector<" + re1.cap(1) + ">"); + } + + // std::list + static QRegExp re2("std::list<(.*)\\s*,std::allocator<(.*)>\\s*>"); + re2.setMinimal(true); for (int i = 0; i != 10; ++i) { - if (re.indexIn(type) == -1 || re.cap(1) != re.cap(2)) + if (re2.indexIn(type) == -1 || re2.cap(1) != re2.cap(2)) break; - type.replace(re.cap(0), "std::vector<" + re.cap(1) + ">"); + type.replace(re2.cap(0), "std::list<" + re2.cap(1) + ">"); } type.replace(" >", ">"); diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp index 958c8985b05..4dc01961958 100644 --- a/tests/manual/gdbdebugger/simple/app.cpp +++ b/tests/manual/gdbdebugger/simple/app.cpp @@ -53,6 +53,8 @@ #include <QtNetwork/QHostAddress> #include <iostream> +#include <list> +#include <stack> #include <string> #include <vector> @@ -373,65 +375,63 @@ void stringRefTest(const QString &refstring) Q_UNUSED(refstring); } - -int F(int a, int b) -{ - return a + b; -} - -int add(int i) { return i + 2; } - -int mul(int i) { return i * 2; } - - -void testStdVector() +void testStdList() { - int x = F(add(1), mul(2)); - Q_UNUSED(x); - std::vector<int *> plist1; + std::list<int *> plist1; plist1.push_back(new int(1)); plist1.push_back(0); plist1.push_back(new int(2)); - std::vector<int> flist2; + std::list<int> flist2; flist2.push_back(1); flist2.push_back(2); flist2.push_back(3); flist2.push_back(4); - int a = 1; - int b = 0; - - while (0) { - a += 1; - if (b) - break; - } - flist2.push_back(1); flist2.push_back(2); flist2.push_back(3); flist2.push_back(4); - std::vector<Foo *> plist; + std::list<Foo *> plist; plist.push_back(new Foo(1)); plist.push_back(0); plist.push_back(new Foo(2)); - std::vector<Foo> flist; + std::list<Foo> flist; flist.push_back(1); - flist.push_back(2); flist.push_back(3); flist.push_back(4); - //flist.takeFirst(); - //flist.takeFirst(); - std::vector<bool> vec; + std::list<bool> vec; vec.push_back(true); vec.push_back(false); } +void testStdStack() +{ + std::stack<int *> plist1; + plist1.push(new int(1)); + plist1.push(0); + plist1.push(new int(2)); + plist1.pop(); + plist1.pop(); + plist1.pop(); + + std::stack<int> flist2; + flist2.push(1); + flist2.push(2); + + std::stack<Foo *> plist; + plist.push(new Foo(1)); + plist.push(new Foo(2)); + + std::stack<Foo> flist; + flist.push(1); + flist.push(2); +} + void testStdString() { QString foo; @@ -470,6 +470,42 @@ void testStdString() v.push_back(str); } +void testStdVector() +{ + std::vector<int *> plist1; + plist1.push_back(new int(1)); + plist1.push_back(0); + plist1.push_back(new int(2)); + + std::vector<int> flist2; + flist2.push_back(1); + flist2.push_back(2); + flist2.push_back(3); + flist2.push_back(4); + + flist2.push_back(1); + flist2.push_back(2); + flist2.push_back(3); + flist2.push_back(4); + + std::vector<Foo *> plist; + plist.push_back(new Foo(1)); + plist.push_back(0); + plist.push_back(new Foo(2)); + + std::vector<Foo> flist; + flist.push_back(1); + flist.push_back(2); + flist.push_back(3); + flist.push_back(4); + //flist.takeFirst(); + //flist.takeFirst(); + + std::vector<bool> vec; + vec.push_back(true); + vec.push_back(false); +} + void testString() { QString str = "Hello "; @@ -729,16 +765,9 @@ void testNamespace() bar.doit(1); } -int main(int argc, char *argv[]) -{ - testIO(); - //QString s; - //s = "hallo"; - //QList<QVector<int> *> vi; - //QList<QVector<double> *> vd; - //int n = A::barz(); - +void testHidden() +{ int n = 1; n = 2; n = 3; @@ -762,10 +791,18 @@ int main(int argc, char *argv[]) } ++n; ++n; +} +int main(int argc, char *argv[]) +{ + //testIO(); + testHidden(); testArray(); - testStdVector(); + + testStdList(); + testStdStack(); testStdString(); + testStdVector(); testPlugin(); testList(); -- GitLab