forked from qt-creator/qt-creator
debugger: also simplify diplayed type of nested std::containers
This commit is contained in:
@@ -896,6 +896,7 @@ static void qDumpQAbstractItem(QDumper &d)
|
|||||||
d.endHash();
|
d.endHash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
d.beginHash();
|
d.beginHash();
|
||||||
P(d, "name", "DisplayRole");
|
P(d, "name", "DisplayRole");
|
||||||
P(d, "numchild", 0);
|
P(d, "numchild", 0);
|
||||||
@@ -903,6 +904,7 @@ static void qDumpQAbstractItem(QDumper &d)
|
|||||||
P(d, "valueencoded", 2);
|
P(d, "valueencoded", 2);
|
||||||
P(d, "type", NS"QString");
|
P(d, "type", NS"QString");
|
||||||
d.endHash();
|
d.endHash();
|
||||||
|
*/
|
||||||
d << "]";
|
d << "]";
|
||||||
}
|
}
|
||||||
d.disarm();
|
d.disarm();
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>425</width>
|
<width>567</width>
|
||||||
<height>127</height>
|
<height>126</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|||||||
@@ -389,88 +389,92 @@ static QString chopConst(QString type)
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString niceType(QString type)
|
QString niceType(QString type)
|
||||||
{
|
{
|
||||||
if (type.contains(QLatin1String("std::"))) {
|
type.replace('*', '@');
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
int start = type.indexOf("std::allocator<");
|
||||||
|
if (start == -1)
|
||||||
|
break;
|
||||||
|
// search for matching '>'
|
||||||
|
int pos;
|
||||||
|
int level = 0;
|
||||||
|
for (pos = start + 12; pos < type.size(); ++pos) {
|
||||||
|
int c = type.at(pos).unicode();
|
||||||
|
if (c == '<') {
|
||||||
|
++level;
|
||||||
|
} else if (c == '>') {
|
||||||
|
--level;
|
||||||
|
if (level == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString alloc = type.mid(start, pos + 1 - start).trimmed();
|
||||||
|
QString inner = alloc.mid(15, alloc.size() - 16).trimmed();
|
||||||
|
|
||||||
|
if (inner == QLatin1String("char"))
|
||||||
// std::string
|
// std::string
|
||||||
type.replace(QLatin1String("basic_string<char, std::char_traits<char>, "
|
type.replace(QLatin1String("basic_string<char, std::char_traits<char>, "
|
||||||
"std::allocator<char> >"), QLatin1String("string"));
|
"std::allocator<char> >"), QLatin1String("string"));
|
||||||
|
else if (inner == QLatin1String("wchar_t"))
|
||||||
// std::wstring
|
// std::wstring
|
||||||
type.replace(QLatin1String("basic_string<wchar_t, std::char_traits<wchar_t>, "
|
type.replace(QLatin1String("basic_string<wchar_t, std::char_traits<wchar_t>, "
|
||||||
"std::allocator<wchar_t> >"), QLatin1String("wstring"));
|
"std::allocator<wchar_t> >"), QLatin1String("wstring"));
|
||||||
|
|
||||||
// std::vector
|
// std::vector, std::deque, std::list
|
||||||
static QRegExp re1(QLatin1String("vector<(.*), std::allocator<(.*)>\\s*>"));
|
QRegExp re1(QString("(vector|list|deque)<%1, %2\\s*>").arg(inner, alloc));
|
||||||
re1.setMinimal(true);
|
if (re1.indexIn(type) != -1)
|
||||||
for (int i = 0; i != 10; ++i) {
|
type.replace(re1.cap(0), QString("%1<%2>").arg(re1.cap(1), inner));
|
||||||
if (re1.indexIn(type) == -1 || re1.cap(1) != re1.cap(2))
|
|
||||||
break;
|
|
||||||
type.replace(re1.cap(0), QLatin1String("vector<") + re1.cap(1) + QLatin1Char('>'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::deque
|
|
||||||
static QRegExp re5(QLatin1String("deque<(.*), std::allocator<(.*)>\\s*>"));
|
|
||||||
re5.setMinimal(true);
|
|
||||||
for (int i = 0; i != 10; ++i) {
|
|
||||||
if (re5.indexIn(type) == -1 || re5.cap(1) != re5.cap(2))
|
|
||||||
break;
|
|
||||||
type.replace(re5.cap(0), QLatin1String("deque<") + re5.cap(1) + QLatin1Char('>'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::stack
|
// std::stack
|
||||||
static QRegExp re6(QLatin1String("stack<(.*), std::deque<(.*), std::allocator<(.*)>\\s*> >"));
|
QRegExp re6(QString("stack<%1, std::deque<%2> >").arg(inner, inner));
|
||||||
re6.setMinimal(true);
|
re6.setMinimal(true);
|
||||||
for (int i = 0; i != 10; ++i) {
|
if (re6.indexIn(type) != -1)
|
||||||
if (re6.indexIn(type) == -1 || re6.cap(1) != re6.cap(2)
|
type.replace(re6.cap(0), QString("stack<%1>").arg(inner));
|
||||||
|| re6.cap(1) != re6.cap(2))
|
|
||||||
break;
|
|
||||||
type.replace(re6.cap(0), QLatin1String("stack<") + re6.cap(1) + QLatin1Char('>'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::list
|
|
||||||
static QRegExp re2(QLatin1String("list<(.*), std::allocator<(.*)>\\s*>"));
|
|
||||||
re2.setMinimal(true);
|
|
||||||
for (int i = 0; i != 10; ++i) {
|
|
||||||
if (re2.indexIn(type) == -1 || re2.cap(1) != re2.cap(2))
|
|
||||||
break;
|
|
||||||
type.replace(re2.cap(0), QLatin1String("list<") + re2.cap(1) + QLatin1Char('>'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::map
|
|
||||||
{
|
|
||||||
static QRegExp re(QLatin1String("map<(.*), (.*), std::less<(.*)>, "
|
|
||||||
"std::allocator<std::pair<(.*), (.*)> > >"));
|
|
||||||
re.setMinimal(true);
|
|
||||||
for (int i = 0; i != 10; ++i) {
|
|
||||||
if (re.indexIn(type) == -1)
|
|
||||||
break;
|
|
||||||
QString key = chopConst(re.cap(1));
|
|
||||||
QString value = chopConst(re.cap(2));
|
|
||||||
QString key1 = chopConst(re.cap(3));
|
|
||||||
QString key2 = chopConst(re.cap(4));
|
|
||||||
QString value2 = chopConst(re.cap(5));
|
|
||||||
if (value != value2 || key != key1 || key != key2) {
|
|
||||||
qDebug() << key << key1 << key2 << value << value2
|
|
||||||
<< (key == key1) << (key == key2) << (value == value2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
type.replace(re.cap(0), QString("map<%1, %2>").arg(key).arg(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::set
|
// std::set
|
||||||
static QRegExp re4(QLatin1String("set<(.*), std::less<(.*)>, std::allocator<(.*)>\\s*>"));
|
QRegExp re4(QString("set<%1, std::less<%2>, %3\\s*>").arg(inner, inner, alloc));
|
||||||
re1.setMinimal(true);
|
re4.setMinimal(true);
|
||||||
for (int i = 0; i != 10; ++i) {
|
if (re4.indexIn(type) != -1)
|
||||||
if (re4.indexIn(type) == -1 || re4.cap(1) != re4.cap(2)
|
type.replace(re4.cap(0), QString("set<%1>").arg(inner));
|
||||||
|| re4.cap(1) != re4.cap(3))
|
|
||||||
break;
|
|
||||||
type.replace(re4.cap(0), QLatin1String("set<") + re4.cap(1) + QLatin1Char('>'));
|
|
||||||
}
|
|
||||||
|
|
||||||
type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));
|
|
||||||
|
// std::map
|
||||||
|
if (inner.startsWith("std::pair<")) {
|
||||||
|
// search for outermost ','
|
||||||
|
int pos;
|
||||||
|
int level = 0;
|
||||||
|
for (pos = 10; pos < inner.size(); ++pos) {
|
||||||
|
int c = inner.at(pos).unicode();
|
||||||
|
if (c == '<')
|
||||||
|
++level;
|
||||||
|
else if (c == '>')
|
||||||
|
--level;
|
||||||
|
else if (c == ',' && level == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
QString ckey = inner.mid(10, pos - 10);
|
||||||
|
QString key = chopConst(ckey);
|
||||||
|
QString value = inner.mid(pos + 2, inner.size() - 3 - pos);
|
||||||
|
|
||||||
|
QRegExp re5(QString("map<%1, %2, std::less<%3>, %4\\s*>")
|
||||||
|
.arg(key, value, key, alloc));
|
||||||
|
re5.setMinimal(true);
|
||||||
|
if (re5.indexIn(type) != -1)
|
||||||
|
type.replace(re5.cap(0), QString("map<%1, %2>").arg(key, value));
|
||||||
|
else {
|
||||||
|
QRegExp re7(QString("map<const %1, %2, std::less<const %3>, %4\\s*>")
|
||||||
|
.arg(key, value, key, alloc));
|
||||||
|
re7.setMinimal(true);
|
||||||
|
if (re7.indexIn(type) != -1)
|
||||||
|
type.replace(re7.cap(0), QString("map<const %1, %2>").arg(key, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type.replace('@', '*');
|
||||||
|
type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,9 @@ private:
|
|||||||
|
|
||||||
QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d);
|
QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d);
|
||||||
|
|
||||||
|
// remove the default template argument in std:: containers
|
||||||
|
QString removeDefaultTemplateArguments(QString type);
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ DEBUGGERDIR = ../../../src/plugins/debugger
|
|||||||
UTILSDIR = ../../../src/libs
|
UTILSDIR = ../../../src/libs
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$DEBUGGERDIR/gdbmi.cpp \
|
$$DEBUGGERDIR/gdb/gdbmi.cpp \
|
||||||
$$DEBUGGERDIR/json.cpp \
|
$$DEBUGGERDIR/tcf/json.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
|
||||||
INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR
|
INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
#include "gdbmi.h"
|
#include "gdb/gdbmi.h"
|
||||||
#include "json.h"
|
#include "tcf/json.h"
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QProcess>
|
#include <QtCore/QProcess>
|
||||||
@@ -95,6 +95,8 @@ private slots:
|
|||||||
void json1() { testJson(jsont1); }
|
void json1() { testJson(jsont1); }
|
||||||
|
|
||||||
void infoBreak();
|
void infoBreak();
|
||||||
|
void niceType();
|
||||||
|
void niceType_data();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void runQtc();
|
void runQtc();
|
||||||
@@ -118,7 +120,6 @@ static QByteArray stripped(QByteArray ba)
|
|||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tst_Debugger::infoBreak()
|
void tst_Debugger::infoBreak()
|
||||||
{
|
{
|
||||||
// This tests the regular expression used in GdbEngine::extractDataFromInfoBreak
|
// This tests the regular expression used in GdbEngine::extractDataFromInfoBreak
|
||||||
@@ -153,6 +154,151 @@ void tst_Debugger::infoBreak()
|
|||||||
QCOMPARE(re.cap(4), QString("124"));
|
QCOMPARE(re.cap(4), QString("124"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString chopConst(QString type)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
if (type.startsWith("const"))
|
||||||
|
type = type.mid(5);
|
||||||
|
else if (type.startsWith(' '))
|
||||||
|
type = type.mid(1);
|
||||||
|
else if (type.endsWith("const"))
|
||||||
|
type.chop(5);
|
||||||
|
else if (type.endsWith(' '))
|
||||||
|
type.chop(1);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString niceType(QString type)
|
||||||
|
{
|
||||||
|
type.replace('*', '@');
|
||||||
|
|
||||||
|
int pos;
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
int start = type.indexOf("std::allocator<");
|
||||||
|
if (start == -1)
|
||||||
|
break;
|
||||||
|
// search for matching '>'
|
||||||
|
int pos;
|
||||||
|
int level = 0;
|
||||||
|
for (pos = start + 12; pos < type.size(); ++pos) {
|
||||||
|
int c = type.at(pos).unicode();
|
||||||
|
if (c == '<') {
|
||||||
|
++level;
|
||||||
|
} else if (c == '>') {
|
||||||
|
--level;
|
||||||
|
if (level == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString alloc = type.mid(start, pos + 1 - start).trimmed();
|
||||||
|
QString inner = alloc.mid(15, alloc.size() - 16).trimmed();
|
||||||
|
//qDebug() << "MATCH: " << pos << alloc << inner;
|
||||||
|
|
||||||
|
if (inner == QLatin1String("char"))
|
||||||
|
// std::string
|
||||||
|
type.replace(QLatin1String("basic_string<char, std::char_traits<char>, "
|
||||||
|
"std::allocator<char> >"), QLatin1String("string"));
|
||||||
|
else if (inner == QLatin1String("wchar_t"))
|
||||||
|
// std::wstring
|
||||||
|
type.replace(QLatin1String("basic_string<wchar_t, std::char_traits<wchar_t>, "
|
||||||
|
"std::allocator<wchar_t> >"), QLatin1String("wstring"));
|
||||||
|
|
||||||
|
// std::vector, std::deque, std::list
|
||||||
|
QRegExp re1(QString("(vector|list|deque)<%1, %2\\s*>").arg(inner, alloc));
|
||||||
|
if (re1.indexIn(type) != -1)
|
||||||
|
type.replace(re1.cap(0), QString("%1<%2>").arg(re1.cap(1), inner));
|
||||||
|
|
||||||
|
|
||||||
|
// std::stack
|
||||||
|
QRegExp re6(QString("stack<%1, std::deque<%2> >").arg(inner, inner));
|
||||||
|
re6.setMinimal(true);
|
||||||
|
if (re6.indexIn(type) != -1)
|
||||||
|
type.replace(re6.cap(0), QString("stack<%1>").arg(inner));
|
||||||
|
|
||||||
|
// std::set
|
||||||
|
QRegExp re4(QString("set<%1, std::less<%2>, %3\\s*>").arg(inner, inner, alloc));
|
||||||
|
re4.setMinimal(true);
|
||||||
|
if (re4.indexIn(type) != -1)
|
||||||
|
type.replace(re4.cap(0), QString("set<%1>").arg(inner));
|
||||||
|
|
||||||
|
|
||||||
|
// std::map
|
||||||
|
if (inner.startsWith("std::pair<")) {
|
||||||
|
// search for outermost ','
|
||||||
|
int pos;
|
||||||
|
int level = 0;
|
||||||
|
for (pos = 10; pos < inner.size(); ++pos) {
|
||||||
|
int c = inner.at(pos).unicode();
|
||||||
|
if (c == '<')
|
||||||
|
++level;
|
||||||
|
else if (c == '>')
|
||||||
|
--level;
|
||||||
|
else if (c == ',' && level == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QString ckey = inner.mid(10, pos - 10);
|
||||||
|
QString key = chopConst(ckey);
|
||||||
|
QString value = inner.mid(pos + 2, inner.size() - 3 - pos);
|
||||||
|
|
||||||
|
QRegExp re5(QString("map<%1, %2, std::less<%3>, %4\\s*>")
|
||||||
|
.arg(key, value, key, alloc));
|
||||||
|
re5.setMinimal(true);
|
||||||
|
if (re5.indexIn(type) != -1)
|
||||||
|
type.replace(re5.cap(0), QString("map<%1, %2>").arg(key, value));
|
||||||
|
else {
|
||||||
|
QRegExp re7(QString("map<const %1, %2, std::less<const %3>, %4\\s*>")
|
||||||
|
.arg(key, value, key, alloc));
|
||||||
|
re7.setMinimal(true);
|
||||||
|
if (re7.indexIn(type) != -1)
|
||||||
|
type.replace(re7.cap(0), QString("map<const %1, %2>").arg(key, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type.replace('@', '*');
|
||||||
|
type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_Debugger::niceType()
|
||||||
|
{
|
||||||
|
// cf. watchutils.cpp
|
||||||
|
QFETCH(QString, input);
|
||||||
|
QFETCH(QString, simplified);
|
||||||
|
QCOMPARE(::niceType(input), simplified);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_Debugger::niceType_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("input");
|
||||||
|
QTest::addColumn<QString>("simplified");
|
||||||
|
|
||||||
|
QTest::newRow("list")
|
||||||
|
<< "std::list<int, std::allocator<int> >"
|
||||||
|
<< "std::list<int>";
|
||||||
|
|
||||||
|
QTest::newRow("combined")
|
||||||
|
<< "std::vector<std::list<int, std::allocator<int> >*, "
|
||||||
|
"std::allocator<std::list<int, std::allocator<int> >*> >"
|
||||||
|
<< "std::vector<std::list<int>*>";
|
||||||
|
|
||||||
|
QTest::newRow("stack")
|
||||||
|
<< "std::stack<int, std::deque<int, std::allocator<int> > >"
|
||||||
|
<< "std::stack<int>";
|
||||||
|
|
||||||
|
QTest::newRow("map")
|
||||||
|
<< "std::map<myns::QString, Foo, std::less<myns::QString>, "
|
||||||
|
"std::allocator<std::pair<const myns::QString, Foo> > >"
|
||||||
|
<< "std::map<myns::QString, Foo>";
|
||||||
|
|
||||||
|
QTest::newRow("map2")
|
||||||
|
<< "std::map<const char*, Foo, std::less<const char*>, "
|
||||||
|
"std::allocator<std::pair<const char* const, Foo> > >"
|
||||||
|
<< "std::map<const char*, Foo>";
|
||||||
|
}
|
||||||
|
|
||||||
void tst_Debugger::readStandardOutput()
|
void tst_Debugger::readStandardOutput()
|
||||||
{
|
{
|
||||||
qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput());
|
qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput());
|
||||||
|
|||||||
@@ -818,7 +818,7 @@ void testQStandardItemModel()
|
|||||||
<< (i11 = new QStandardItem("11")) << (new QStandardItem("aa")));
|
<< (i11 = new QStandardItem("11")) << (new QStandardItem("aa")));
|
||||||
int i = 1;
|
int i = 1;
|
||||||
++i;
|
++i;
|
||||||
++i;
|
+i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testQString()
|
void testQString()
|
||||||
@@ -1118,8 +1118,41 @@ void testHidden()
|
|||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testObject1()
|
||||||
|
{
|
||||||
|
QObject parent;
|
||||||
|
parent.setObjectName("A Parent");
|
||||||
|
QObject child(&parent);
|
||||||
|
child.setObjectName("A Child");
|
||||||
|
child.setObjectName("A renamed Child");
|
||||||
|
}
|
||||||
|
|
||||||
|
void testVector1()
|
||||||
|
{
|
||||||
|
std::vector<std::list<int> *> vector;
|
||||||
|
std::list<int> list;
|
||||||
|
vector.push_back(new std::list<int>(list));
|
||||||
|
vector.push_back(0);
|
||||||
|
list.push_back(45);
|
||||||
|
vector.push_back(new std::list<int>(list));
|
||||||
|
vector.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testQHash1()
|
||||||
|
{
|
||||||
|
QHash<QString, QList<int> > hash;
|
||||||
|
hash.insert("Hallo", QList<int>());
|
||||||
|
hash.insert("Welt", QList<int>() << 1);
|
||||||
|
hash.insert("!", QList<int>() << 1 << 2);
|
||||||
|
hash.insert("!", QList<int>() << 1 << 2);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
testObject1();
|
||||||
|
testVector1();
|
||||||
|
testQHash1();
|
||||||
|
|
||||||
QString hallo = "hallo";
|
QString hallo = "hallo";
|
||||||
QStringList list;
|
QStringList list;
|
||||||
list << "aaa" << "bbb" << "cc";
|
list << "aaa" << "bbb" << "cc";
|
||||||
|
|||||||
Reference in New Issue
Block a user