Commit 69f58777 authored by hjk's avatar hjk
Browse files

debugger: also simplify diplayed type of nested std::containers

parent 3a851daf
......@@ -896,6 +896,7 @@ static void qDumpQAbstractItem(QDumper &d)
d.endHash();
}
}
/*
d.beginHash();
P(d, "name", "DisplayRole");
P(d, "numchild", 0);
......@@ -903,6 +904,7 @@ static void qDumpQAbstractItem(QDumper &d)
P(d, "valueencoded", 2);
P(d, "type", NS"QString");
d.endHash();
*/
d << "]";
}
d.disarm();
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>425</width>
<height>127</height>
<width>567</width>
<height>126</height>
</rect>
</property>
<property name="windowTitle">
......
......@@ -389,88 +389,92 @@ static QString chopConst(QString type)
return type;
}
static QString niceType(QString type)
QString niceType(QString type)
{
if (type.contains(QLatin1String("std::"))) {
// std::string
type.replace(QLatin1String("basic_string<char, std::char_traits<char>, "
"std::allocator<char> >"), QLatin1String("string"));
// std::wstring
type.replace(QLatin1String("basic_string<wchar_t, std::char_traits<wchar_t>, "
"std::allocator<wchar_t> >"), QLatin1String("wstring"));
// std::vector
static QRegExp re1(QLatin1String("vector<(.*), 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), QLatin1String("vector<") + re1.cap(1) + QLatin1Char('>'));
}
type.replace('*', '@');
// 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('>'));
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
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
static QRegExp re6(QLatin1String("stack<(.*), std::deque<(.*), std::allocator<(.*)>\\s*> >"));
QRegExp re6(QString("stack<%1, std::deque<%2> >").arg(inner, inner));
re6.setMinimal(true);
for (int i = 0; i != 10; ++i) {
if (re6.indexIn(type) == -1 || re6.cap(1) != re6.cap(2)
|| re6.cap(1) != re6.cap(2))
break;
type.replace(re6.cap(0), QLatin1String("stack<") + re6.cap(1) + QLatin1Char('>'));
}
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::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);
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;
}
type.replace(re.cap(0), QString("map<%1, %2>").arg(key).arg(value));
}
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));
}
}
// std::set
static QRegExp re4(QLatin1String("set<(.*), std::less<(.*)>, std::allocator<(.*)>\\s*>"));
re1.setMinimal(true);
for (int i = 0; i != 10; ++i) {
if (re4.indexIn(type) == -1 || re4.cap(1) != re4.cap(2)
|| re4.cap(1) != re4.cap(3))
break;
type.replace(re4.cap(0), QLatin1String("set<") + re4.cap(1) + QLatin1Char('>'));
}
type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));
}
type.replace('@', '*');
type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));
return type;
}
......
......@@ -225,6 +225,9 @@ private:
QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d);
// remove the default template argument in std:: containers
QString removeDefaultTemplateArguments(QString type);
} // namespace Internal
} // namespace Debugger
......
......@@ -5,8 +5,8 @@ DEBUGGERDIR = ../../../src/plugins/debugger
UTILSDIR = ../../../src/libs
SOURCES += \
$$DEBUGGERDIR/gdbmi.cpp \
$$DEBUGGERDIR/json.cpp \
$$DEBUGGERDIR/gdb/gdbmi.cpp \
$$DEBUGGERDIR/tcf/json.cpp \
main.cpp \
INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR
......
#include "gdbmi.h"
#include "json.h"
#include "gdb/gdbmi.h"
#include "tcf/json.h"
#include <QtCore/QObject>
#include <QtCore/QProcess>
......@@ -95,6 +95,8 @@ private slots:
void json1() { testJson(jsont1); }
void infoBreak();
void niceType();
void niceType_data();
public slots:
void runQtc();
......@@ -118,7 +120,6 @@ static QByteArray stripped(QByteArray ba)
return ba;
}
void tst_Debugger::infoBreak()
{
// This tests the regular expression used in GdbEngine::extractDataFromInfoBreak
......@@ -153,6 +154,151 @@ void tst_Debugger::infoBreak()
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()
{
qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput());
......
......@@ -818,7 +818,7 @@ void testQStandardItemModel()
<< (i11 = new QStandardItem("11")) << (new QStandardItem("aa")));
int i = 1;
++i;
++i;
+i;
}
void testQString()
......@@ -1118,8 +1118,41 @@ void testHidden()
++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[])
{
testObject1();
testVector1();
testQHash1();
QString hallo = "hallo";
QStringList list;
list << "aaa" << "bbb" << "cc";
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment