debugger: show non-ASCII in QString, too

This commit is contained in:
hjk
2009-04-02 10:54:22 +02:00
parent afa7aec596
commit 47995286b5
6 changed files with 57 additions and 53 deletions

View File

@@ -602,8 +602,7 @@ QDumper &QDumper::operator<<(const QByteArray &ba)
QDumper &QDumper::operator<<(const QString &str) QDumper &QDumper::operator<<(const QString &str)
{ {
QByteArray ba = str.toUtf8(); putBase64Encoded((const char *)str.constData(), 2 * str.size());
putBase64Encoded(ba.constData(), ba.size());
return *this; return *this;
} }
@@ -649,7 +648,7 @@ void QDumper::putEllipsis()
P(dumper, "value", value); \ P(dumper, "value", value); \
P(dumper, "type", NS"QString"); \ P(dumper, "type", NS"QString"); \
P(dumper, "numchild", "0"); \ P(dumper, "numchild", "0"); \
P(dumper, "valueencoded", "1"); \ P(dumper, "valueencoded", "2"); \
dumper.endHash(); dumper.endHash();
// simple integer property // simple integer property
@@ -680,7 +679,7 @@ void QDumper::putEllipsis()
P(dumper, "name", name); \ P(dumper, "name", name); \
P(dumper, "value", QString(QLatin1String("'%1' (%2, 0x%3)")) \ P(dumper, "value", QString(QLatin1String("'%1' (%2, 0x%3)")) \
.arg(value).arg(value.unicode()).arg(value.unicode(), 0, 16)); \ .arg(value).arg(value.unicode()).arg(value.unicode(), 0, 16)); \
P(dumper, "valueencoded", "1"); \ P(dumper, "valueencoded", "2"); \
P(dumper, "type", NS"QChar"); \ P(dumper, "type", NS"QChar"); \
P(dumper, "numchild", "0"); \ P(dumper, "numchild", "0"); \
dumper.endHash(); dumper.endHash();
@@ -755,7 +754,7 @@ static void qDumpInnerValueHelper(QDumper &d, const char *type, const void *addr
const QObject *ob = reinterpret_cast<const QObject *>(addr); const QObject *ob = reinterpret_cast<const QObject *>(addr);
P(d, "addr", ob); P(d, "addr", ob);
P(d, "value", ob->objectName()); P(d, "value", ob->objectName());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QObject"); P(d, "type", NS"QObject");
P(d, "displayedtype", ob->metaObject()->className()); P(d, "displayedtype", ob->metaObject()->className());
} else { } else {
@@ -767,7 +766,7 @@ static void qDumpInnerValueHelper(QDumper &d, const char *type, const void *addr
case 'S': case 'S':
if (isEqual(type, "QString")) { if (isEqual(type, "QString")) {
d.addCommaIfNeeded(); d.addCommaIfNeeded();
d << field << "encoded=\"1\","; d << field << "encoded=\"2\",";
P(d, field, *(QString*)addr); P(d, field, *(QString*)addr);
} }
return; return;
@@ -857,7 +856,7 @@ static void qDumpQDateTime(QDumper &d)
P(d, "value", "(null)"); P(d, "value", "(null)");
} else { } else {
P(d, "value", date.toString()); P(d, "value", date.toString());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
} }
P(d, "type", NS"QDateTime"); P(d, "type", NS"QDateTime");
P(d, "numchild", "3"); P(d, "numchild", "3");
@@ -901,7 +900,7 @@ static void qDumpQDir(QDumper &d)
{ {
const QDir &dir = *reinterpret_cast<const QDir *>(d.data); const QDir &dir = *reinterpret_cast<const QDir *>(d.data);
P(d, "value", dir.path()); P(d, "value", dir.path());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QDir"); P(d, "type", NS"QDir");
P(d, "numchild", "3"); P(d, "numchild", "3");
if (d.dumpChildren) { if (d.dumpChildren) {
@@ -917,7 +916,7 @@ static void qDumpQFile(QDumper &d)
{ {
const QFile &file = *reinterpret_cast<const QFile *>(d.data); const QFile &file = *reinterpret_cast<const QFile *>(d.data);
P(d, "value", file.fileName()); P(d, "value", file.fileName());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QFile"); P(d, "type", NS"QFile");
P(d, "numchild", "2"); P(d, "numchild", "2");
if (d.dumpChildren) { if (d.dumpChildren) {
@@ -933,7 +932,7 @@ static void qDumpQFileInfo(QDumper &d)
{ {
const QFileInfo &info = *reinterpret_cast<const QFileInfo *>(d.data); const QFileInfo &info = *reinterpret_cast<const QFileInfo *>(d.data);
P(d, "value", info.filePath()); P(d, "value", info.filePath());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QFileInfo"); P(d, "type", NS"QFileInfo");
P(d, "numchild", "3"); P(d, "numchild", "3");
if (d.dumpChildren) { if (d.dumpChildren) {
@@ -980,7 +979,7 @@ static void qDumpQFileInfo(QDumper &d)
d.beginHash(); d.beginHash();
P(d, "name", "created"); P(d, "name", "created");
P(d, "value", info.created().toString()); P(d, "value", info.created().toString());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->created()"); P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->created()");
P(d, "type", NS"QDateTime"); P(d, "type", NS"QDateTime");
P(d, "numchild", "1"); P(d, "numchild", "1");
@@ -989,7 +988,7 @@ static void qDumpQFileInfo(QDumper &d)
d.beginHash(); d.beginHash();
P(d, "name", "lastModified"); P(d, "name", "lastModified");
P(d, "value", info.lastModified().toString()); P(d, "value", info.lastModified().toString());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->lastModified()"); P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->lastModified()");
P(d, "type", NS"QDateTime"); P(d, "type", NS"QDateTime");
P(d, "numchild", "1"); P(d, "numchild", "1");
@@ -998,7 +997,7 @@ static void qDumpQFileInfo(QDumper &d)
d.beginHash(); d.beginHash();
P(d, "name", "lastRead"); P(d, "name", "lastRead");
P(d, "value", info.lastRead().toString()); P(d, "value", info.lastRead().toString());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->lastRead()"); P(d, "exp", "(("NSX"QFileInfo"NSY"*)" << d.data << ")->lastRead()");
P(d, "type", NS"QDateTime"); P(d, "type", NS"QDateTime");
P(d, "numchild", "1"); P(d, "numchild", "1");
@@ -1296,7 +1295,7 @@ static void qDumpQLocale(QDumper &d)
{ {
const QLocale &locale = *reinterpret_cast<const QLocale *>(d.data); const QLocale &locale = *reinterpret_cast<const QLocale *>(d.data);
P(d, "value", locale.name()); P(d, "value", locale.name());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QLocale"); P(d, "type", NS"QLocale");
P(d, "numchild", "8"); P(d, "numchild", "8");
if (d.dumpChildren) { if (d.dumpChildren) {
@@ -1508,7 +1507,7 @@ static void qDumpQObject(QDumper &d)
const QMetaObject *mo = ob->metaObject(); const QMetaObject *mo = ob->metaObject();
unsigned childrenOffset = d.extraInt[0]; unsigned childrenOffset = d.extraInt[0];
P(d, "value", ob->objectName()); P(d, "value", ob->objectName());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QObject"); P(d, "type", NS"QObject");
P(d, "displayedtype", mo->className()); P(d, "displayedtype", mo->className());
P(d, "numchild", 4); P(d, "numchild", 4);
@@ -1627,7 +1626,7 @@ static void qDumpQObjectPropertyList(QDumper &d)
<< ")->" << prop.name() << "()"); << ")->" << prop.name() << "()");
if (isEqual(prop.typeName(), "QString")) { if (isEqual(prop.typeName(), "QString")) {
P(d, "value", prop.read(ob).toString()); P(d, "value", prop.read(ob).toString());
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QString"); P(d, "type", NS"QString");
P(d, "numchild", "0"); P(d, "numchild", "0");
} else if (isEqual(prop.typeName(), "bool")) { } else if (isEqual(prop.typeName(), "bool")) {
@@ -1941,7 +1940,7 @@ static void qDumpQString(QDumper &d)
} }
P(d, "value", str); P(d, "value", str);
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
P(d, "type", NS"QString"); P(d, "type", NS"QString");
//P(d, "editvalue", str); // handled generically below //P(d, "editvalue", str); // handled generically below
P(d, "numchild", "0"); P(d, "numchild", "0");
@@ -1973,7 +1972,7 @@ static void qDumpQStringList(QDumper &d)
d.beginHash(); d.beginHash();
P(d, "name", i); P(d, "name", i);
P(d, "value", list[i]); P(d, "value", list[i]);
P(d, "valueencoded", "1"); P(d, "valueencoded", "2");
d.endHash(); d.endHash();
} }
if (n < list.size()) if (n < list.size())

View File

@@ -1056,7 +1056,8 @@ void DebuggerManager::sessionLoaded()
void DebuggerManager::sessionUnloaded() void DebuggerManager::sessionUnloaded()
{ {
return; return;
cleanupViews(); //FIXME: Breakview crashes on startup as there is
//cleanupViews();
if (m_engine) if (m_engine)
m_engine->shutdown(); m_engine->shutdown();
setStatus(DebuggerProcessNotReady); setStatus(DebuggerProcessNotReady);

View File

@@ -2776,34 +2776,53 @@ void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
static const QString strNotInScope = QLatin1String("<not in scope>"); static const QString strNotInScope = QLatin1String("<not in scope>");
static QString quoteUnprintableLatin1(const QByteArray &ba)
{
QString res;
char buf[10];
for (int i = 0, n = ba.size(); i != n; ++i) {
unsigned char c = ba.at(i);
if (isprint(c)) {
res += c;
} else {
qsnprintf(buf, sizeof(buf) - 1, "\\%x", int(c));
res += buf;
}
}
return res;
}
static void setWatchDataValue(WatchData &data, const GdbMi &mi, static void setWatchDataValue(WatchData &data, const GdbMi &mi,
int encoding = 0) int encoding = 0)
{ {
if (mi.isValid()) { if (mi.isValid()) {
QByteArray ba; QByteArray ba;
QString str;
switch (encoding) { switch (encoding) {
case 0: // unencoded 8 bit data case 0: // unencoded 8 bit data
ba = mi.data(); ba = mi.data();
str = quoteUnprintableLatin1(ba);
break; break;
case 1: // base64 encoded 8 bit data case 1: // base64 encoded 8 bit data, used for QByteArray
ba = QByteArray::fromBase64(mi.data()); ba = QByteArray::fromBase64(mi.data());
ba = '"' + ba + '"'; str = '"' + quoteUnprintableLatin1(ba) + '"';
break; break;
case 2: // base64 encoded 16 bit data case 2: // base64 encoded 16 bit data, used for QString
ba = QByteArray::fromBase64(mi.data()); ba = QByteArray::fromBase64(mi.data());
ba = QString::fromUtf16((ushort *)ba.data(), ba.size() / 2).toUtf8(); str = QString::fromUtf16((ushort *)ba.data(), ba.size() / 2);
ba = '"' + ba + '"'; str = '"' + str + '"';
break; break;
case 3: // base64 encoded 32 bit data case 3: // base64 encoded 32 bit data
ba = QByteArray::fromBase64(mi.data()); ba = QByteArray::fromBase64(mi.data());
ba = QString::fromUcs4((uint *)ba.data(), ba.size() / 4).toUtf8(); str = QString::fromUcs4((uint *)ba.data(), ba.size() / 4);
ba = '"' + ba + '"'; str = '"' + str + '"';
break; break;
case 4: // base64 encoded 8 bit data case 4: // base64 encoded 16 bit data, without quotes (see 2)
ba = QByteArray::fromBase64(mi.data()); ba = QByteArray::fromBase64(mi.data());
str = QString::fromUtf16((ushort *)ba.data(), ba.size() / 2);
break; break;
} }
data.setValue(ba); data.setValue(str);
} else { } else {
data.setValueNeeded(); data.setValueNeeded();
} }
@@ -3411,7 +3430,7 @@ void GdbEngine::handleVarCreate(const GdbResultRecord &record,
data.setChildrenNeeded(); data.setChildrenNeeded();
setWatchDataChildCount(data, record.data.findChild("numchild")); setWatchDataChildCount(data, record.data.findChild("numchild"));
//if (data.isValueNeeded() && data.childCount > 0) //if (data.isValueNeeded() && data.childCount > 0)
// data.setValue(QByteArray()); // data.setValue(QString());
insertData(data); insertData(data);
} }
} else if (record.resultClass == GdbResultError) { } else if (record.resultClass == GdbResultError) {
@@ -3607,13 +3626,13 @@ void GdbEngine::handleDumpCustomValue3(const GdbResultRecord &record,
QString str; QString str;
for (int i = 0; i < list.size(); ++i) for (int i = 0; i < list.size(); ++i)
str.append(list.at(i).toInt()); str.append(list.at(i).toInt());
data.setValue('"' + str.toUtf8() + '"'); data.setValue('"' + str + '"');
data.setChildCount(0); data.setChildCount(0);
data.setAllUnneeded(); data.setAllUnneeded();
insertData(data); insertData(data);
} else if (data.type == "QStringList" || data.type.endsWith("::QStringList")) { } else if (data.type == "QStringList" || data.type.endsWith("::QStringList")) {
int l = list.size(); int l = list.size();
data.setValue(QString("<%1 items>").arg(l).toLatin1()); data.setValue(tr("<%1 items>").arg(l));
data.setChildCount(list.size()); data.setChildCount(list.size());
data.setAllUnneeded(); data.setAllUnneeded();
insertData(data); insertData(data);

View File

@@ -91,25 +91,9 @@ void WatchData::setError(const QString &msg)
valuedisabled = true; valuedisabled = true;
} }
static QByteArray quoteUnprintable(const QByteArray &ba) void WatchData::setValue(const QString &value0)
{ {
QByteArray res; value = value0;
char buf[10];
for (int i = 0, n = ba.size(); i != n; ++i) {
unsigned char c = ba.at(i);
if (isprint(c)) {
res += c;
} else {
qsnprintf(buf, sizeof(buf) - 1, "\\%x", int(c));
res += buf;
}
}
return res;
}
void WatchData::setValue(const QByteArray &value0)
{
value = quoteUnprintable(value0);
if (value == "{...}") { if (value == "{...}") {
value.clear(); value.clear();
childCount = 1; // at least one... childCount = 1; // at least one...

View File

@@ -66,7 +66,7 @@ public:
| ChildCountNeeded | ChildCountNeeded
}; };
void setValue(const QByteArray &); void setValue(const QString &);
void setType(const QString &); void setType(const QString &);
void setValueToolTip(const QString &); void setValueToolTip(const QString &);
void setError(const QString &); void setError(const QString &);

View File

@@ -416,7 +416,8 @@ void testQObject(int &argc, char *argv[])
obs.append(&app); obs.append(&app);
ob1.setObjectName("A Subobject"); ob1.setObjectName("A Subobject");
*/ */
QLabel l("XXXXXXXXXXXXXXXXX"); QString str = QString::fromUtf8("XXXXXXXXXXXXXXyyXXX ö");
QLabel l(str);
l.show(); l.show();
app.exec(); app.exec();
} }
@@ -998,6 +999,7 @@ int main(int argc, char *argv[])
testIO(); testIO();
testHidden(); testHidden();
testArray(); testArray();
testQByteArray();
testStdDeque(); testStdDeque();
testStdList(); testStdList();
@@ -1012,7 +1014,6 @@ int main(int argc, char *argv[])
testQLinkedList(); testQLinkedList();
testNamespace(); testNamespace();
//return 0; //return 0;
testQByteArray();
testQHash(); testQHash();
testQImage(); testQImage();
testQMap(); testQMap();