forked from qt-creator/qt-creator
Debugger: Debugger protocol maintenance
- Move DisplayFormat from watchhandler.h to debuggerprotocol.h - Add/update a few comments about the use of the protocol enums - Make decodeData take a DebuggerEncoding instead of an int Change-Id: I50bed70a5da2e94da46e894bf9136bc14c9a1b23 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -59,7 +59,7 @@ StartRemoteProcess, \
|
|||||||
= range(0, 9)
|
= range(0, 9)
|
||||||
|
|
||||||
|
|
||||||
# Known special formats. Keep in sync with DisplayFormat in watchhandler.h
|
# Known special formats. Keep in sync with DisplayFormat in debuggerprotocol.h
|
||||||
AutomaticFormat, \
|
AutomaticFormat, \
|
||||||
RawFormat, \
|
RawFormat, \
|
||||||
SimpleFormat, \
|
SimpleFormat, \
|
||||||
@@ -142,7 +142,7 @@ SpecialOptimizedOutValue, \
|
|||||||
SpecialEmptyStructureValue, \
|
SpecialEmptyStructureValue, \
|
||||||
= range(40)
|
= range(40)
|
||||||
|
|
||||||
# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
|
# Display modes. Keep that synchronized with DebuggerDisplay in debuggerprotocol.h
|
||||||
StopDisplay, \
|
StopDisplay, \
|
||||||
DisplayImageData, \
|
DisplayImageData, \
|
||||||
DisplayUtf16String, \
|
DisplayUtf16String, \
|
||||||
|
@@ -558,7 +558,7 @@ static void getDateTime(qint64 msecs, int status, QDate *date, QTime *time)
|
|||||||
*time = (status & NullTime) ? QTime() : QTime::fromMSecsSinceStartOfDay(ds);
|
*time = (status & NullTime) ? QTime() : QTime::fromMSecsSinceStartOfDay(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString decodeData(const QByteArray &ba, int encoding)
|
QString decodeData(const QByteArray &ba, DebuggerEncoding encoding)
|
||||||
{
|
{
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
case Unencoded8Bit: // 0
|
case Unencoded8Bit: // 0
|
||||||
@@ -657,17 +657,39 @@ QString decodeData(const QByteArray &ba, int encoding)
|
|||||||
const QDate date = dateFromData(ba.toInt());
|
const QDate date = dateFromData(ba.toInt());
|
||||||
return date.isValid() ? date.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
return date.isValid() ? date.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
||||||
}
|
}
|
||||||
case MillisecondsSinceMidnight: {
|
case MillisecondsSinceMidnight: { // 15
|
||||||
const QTime time = timeFromData(ba.toInt());
|
const QTime time = timeFromData(ba.toInt());
|
||||||
return time.isValid() ? time.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
return time.isValid() ? time.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
||||||
}
|
}
|
||||||
case JulianDateAndMillisecondsSinceMidnight: {
|
case JulianDateAndMillisecondsSinceMidnight: { // 16
|
||||||
const int p = ba.indexOf('/');
|
const int p = ba.indexOf('/');
|
||||||
const QDate date = dateFromData(ba.left(p).toInt());
|
const QDate date = dateFromData(ba.left(p).toInt());
|
||||||
const QTime time = timeFromData(ba.mid(p + 1 ).toInt());
|
const QTime time = timeFromData(ba.mid(p + 1 ).toInt());
|
||||||
const QDateTime dateTime = QDateTime(date, time);
|
const QDateTime dateTime = QDateTime(date, time);
|
||||||
return dateTime.isValid() ? dateTime.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
return dateTime.isValid() ? dateTime.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
||||||
}
|
}
|
||||||
|
case Hex2EncodedInt1: // 17
|
||||||
|
case Hex2EncodedInt2: // 18
|
||||||
|
case Hex2EncodedInt4: // 19
|
||||||
|
case Hex2EncodedInt8: // 20
|
||||||
|
case Hex2EncodedUInt1: // 21
|
||||||
|
case Hex2EncodedUInt2: // 22
|
||||||
|
case Hex2EncodedUInt4: // 23
|
||||||
|
case Hex2EncodedUInt8: // 24
|
||||||
|
qDebug("not implemented"); // Only used in Arrays, see watchdata.cpp
|
||||||
|
return QString();
|
||||||
|
case Hex2EncodedFloat4: { // 25
|
||||||
|
const QByteArray s = QByteArray::fromHex(ba);
|
||||||
|
QTC_ASSERT(s.size() == 4, break);
|
||||||
|
union { char c[4]; float f; } u = { { s[3], s[2], s[1], s[0] } };
|
||||||
|
return QString::number(u.f);
|
||||||
|
}
|
||||||
|
case Hex2EncodedFloat8: { // 26
|
||||||
|
const QByteArray s = QByteArray::fromHex(ba);
|
||||||
|
QTC_ASSERT(s.size() == 8, break);
|
||||||
|
union { char c[8]; double d; } u = { { s[7], s[6], s[5], s[4], s[3], s[2], s[1], s[0] } };
|
||||||
|
return QString::number(u.d);
|
||||||
|
}
|
||||||
case IPv6AddressAndHexScopeId: { // 27, 16 hex-encoded bytes, "%" and the string-encoded scope
|
case IPv6AddressAndHexScopeId: { // 27, 16 hex-encoded bytes, "%" and the string-encoded scope
|
||||||
const int p = ba.indexOf('%');
|
const int p = ba.indexOf('%');
|
||||||
QHostAddress ip6(QString::fromLatin1(p == -1 ? ba : ba.left(p)));
|
QHostAddress ip6(QString::fromLatin1(p == -1 ? ba : ba.left(p)));
|
||||||
@@ -716,46 +738,34 @@ QString decodeData(const QByteArray &ba, int encoding)
|
|||||||
}
|
}
|
||||||
return dateTime.toString();
|
return dateTime.toString();
|
||||||
}
|
}
|
||||||
case Hex2EncodedFloat4: {
|
case SpecialEmptyValue: { // 30
|
||||||
const QByteArray s = QByteArray::fromHex(ba);
|
|
||||||
QTC_ASSERT(s.size() == 4, break);
|
|
||||||
union { char c[4]; float f; } u = { { s[3], s[2], s[1], s[0] } };
|
|
||||||
return QString::number(u.f);
|
|
||||||
}
|
|
||||||
case Hex2EncodedFloat8: {
|
|
||||||
const QByteArray s = QByteArray::fromHex(ba);
|
|
||||||
QTC_ASSERT(s.size() == 8, break);
|
|
||||||
union { char c[8]; double d; } u = { { s[7], s[6], s[5], s[4], s[3], s[2], s[1], s[0] } };
|
|
||||||
return QString::number(u.d);
|
|
||||||
}
|
|
||||||
case SpecialEmptyValue: {
|
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<empty>");
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<empty>");
|
||||||
}
|
}
|
||||||
case SpecialUninitializedValue: {
|
case SpecialUninitializedValue: { // 31
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<uninitialized>");
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<uninitialized>");
|
||||||
}
|
}
|
||||||
case SpecialInvalidValue: {
|
case SpecialInvalidValue: { // 32
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<invalid>");
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<invalid>");
|
||||||
}
|
}
|
||||||
case SpecialNotAccessibleValue: {
|
case SpecialNotAccessibleValue: { // 33
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not accessible>");
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not accessible>");
|
||||||
}
|
}
|
||||||
case SpecialItemCountValue: {
|
case SpecialItemCountValue: { // 34
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<%n items>", 0, ba.toInt());
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<%n items>", 0, ba.toInt());
|
||||||
}
|
}
|
||||||
case SpecialMinimumItemCountValue: {
|
case SpecialMinimumItemCountValue: { // 35
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<at least %n items>", 0, ba.toInt());
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<at least %n items>", 0, ba.toInt());
|
||||||
}
|
}
|
||||||
case SpecialNotCallableValue: {
|
case SpecialNotCallableValue: { // 36
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not callable>");
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not callable>");
|
||||||
}
|
}
|
||||||
case SpecialNullReferenceValue: {
|
case SpecialNullReferenceValue: { // 37
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<null reference>");
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<null reference>");
|
||||||
}
|
}
|
||||||
case SpecialOptimizedOutValue: {
|
case SpecialOptimizedOutValue: { // 38
|
||||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<optimized out>");
|
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<optimized out>");
|
||||||
}
|
}
|
||||||
case SpecialEmptyStructureValue: {
|
case SpecialEmptyStructureValue: { // 39
|
||||||
return QLatin1String("{...}");
|
return QLatin1String("{...}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -208,7 +208,13 @@ public:
|
|||||||
void extractGdbVersion(const QString &msg,
|
void extractGdbVersion(const QString &msg,
|
||||||
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb, bool *isQnxGdb);
|
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb, bool *isQnxGdb);
|
||||||
|
|
||||||
|
|
||||||
|
// These enum values correspond to encodings produced by the dumpers
|
||||||
|
// and consumed by \c decodeData(const QByteArray &baIn, DebuggerEncoding encoding);
|
||||||
|
// They are never stored in settings.
|
||||||
|
//
|
||||||
// Keep in sync with dumper.py
|
// Keep in sync with dumper.py
|
||||||
|
|
||||||
enum DebuggerEncoding
|
enum DebuggerEncoding
|
||||||
{
|
{
|
||||||
Unencoded8Bit = 0,
|
Unencoded8Bit = 0,
|
||||||
@@ -253,8 +259,68 @@ enum DebuggerEncoding
|
|||||||
SpecialEmptyStructureValue = 39
|
SpecialEmptyStructureValue = 39
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Decode string data as returned by the dumper helpers.
|
||||||
|
QString decodeData(const QByteArray &baIn, DebuggerEncoding encoding);
|
||||||
|
|
||||||
|
|
||||||
|
// These enum values correspond to possible value display format requests,
|
||||||
|
// typically selected by the user using the L&E context menu, under
|
||||||
|
// "Change Value Display Format". They are passed from the frontend to
|
||||||
|
// the dumpers.
|
||||||
|
//
|
||||||
|
// Keep in sync with dumper.py.
|
||||||
|
//
|
||||||
|
// \note Add new enum values only at the end, as the numeric values are
|
||||||
|
// persisted in user settings.
|
||||||
|
|
||||||
|
enum DisplayFormat
|
||||||
|
{
|
||||||
|
AutomaticFormat = 0, // Based on type for individuals, dumper default for types.
|
||||||
|
// Could be anything reasonably cheap.
|
||||||
|
RawFormat = 1, // No formatting at all.
|
||||||
|
|
||||||
|
SimpleFormat = 2, // Typical simple format (e.g. for QModelIndex row/column)
|
||||||
|
EnhancedFormat = 3, // Enhanced format (e.g. for QModelIndex with resolved display)
|
||||||
|
SeparateFormat = 4, // Display in separate Window
|
||||||
|
|
||||||
|
Latin1StringFormat = 5,
|
||||||
|
SeparateLatin1StringFormat = 6,
|
||||||
|
Utf8StringFormat = 7,
|
||||||
|
SeparateUtf8StringFormat = 8,
|
||||||
|
Local8BitStringFormat = 9,
|
||||||
|
Utf16StringFormat = 10,
|
||||||
|
Ucs4StringFormat = 11,
|
||||||
|
|
||||||
|
Array10Format = 12,
|
||||||
|
Array100Format = 13,
|
||||||
|
Array1000Format = 14,
|
||||||
|
Array10000Format = 15,
|
||||||
|
ArrayPlotFormat = 16,
|
||||||
|
|
||||||
|
CompactMapFormat = 17,
|
||||||
|
DirectQListStorageFormat = 18,
|
||||||
|
IndirectQListStorageFormat = 19,
|
||||||
|
|
||||||
|
BoolTextFormat = 20, // Bools as "true" or "false" - Frontend internal only.
|
||||||
|
BoolIntegerFormat = 21, // Bools as "0" or "1" - Frontend internal only
|
||||||
|
|
||||||
|
DecimalIntegerFormat = 22, // Frontend internal only
|
||||||
|
HexadecimalIntegerFormat = 23, // Frontend internal only
|
||||||
|
BinaryIntegerFormat = 24, // Frontend internal only
|
||||||
|
OctalIntegerFormat = 25, // Frontend internal only
|
||||||
|
|
||||||
|
CompactFloatFormat = 26, // Frontend internal only
|
||||||
|
ScientificFloatFormat = 27 // Frontend internal only
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// These enum values are passed from the dumper to the frontend,
|
||||||
|
// typically as a result of passing a related DisplayFormat value.
|
||||||
|
// They are never stored in settings.
|
||||||
|
|
||||||
// Keep in sync with dumper.py, symbolgroupvalue.cpp of CDB
|
// Keep in sync with dumper.py, symbolgroupvalue.cpp of CDB
|
||||||
enum DebuggerDisplay {
|
enum DebuggerDisplay
|
||||||
|
{
|
||||||
StopDisplay = 0,
|
StopDisplay = 0,
|
||||||
DisplayImageData = 1,
|
DisplayImageData = 1,
|
||||||
DisplayUtf16String = 2,
|
DisplayUtf16String = 2,
|
||||||
@@ -263,8 +329,6 @@ enum DebuggerDisplay {
|
|||||||
DisplayUtf8String = 5,
|
DisplayUtf8String = 5,
|
||||||
DisplayPlotData = 6
|
DisplayPlotData = 6
|
||||||
};
|
};
|
||||||
// Decode string data as returned by the dumper helpers.
|
|
||||||
QString decodeData(const QByteArray &baIn, int encoding);
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -3498,7 +3498,7 @@ void GdbEngine::handleThreadNames(const DebuggerResponse &response)
|
|||||||
ThreadData thread;
|
ThreadData thread;
|
||||||
thread.id = ThreadId(name["id"].toInt());
|
thread.id = ThreadId(name["id"].toInt());
|
||||||
thread.name = decodeData(name["value"].data(),
|
thread.name = decodeData(name["value"].data(),
|
||||||
name["valueencoded"].toInt());
|
DebuggerEncoding(name["valueencoded"].toInt()));
|
||||||
handler->updateThread(thread);
|
handler->updateThread(thread);
|
||||||
}
|
}
|
||||||
updateViews();
|
updateViews();
|
||||||
|
@@ -393,7 +393,7 @@ void WatchData::updateValue(const GdbMi &item)
|
|||||||
GdbMi value = item["value"];
|
GdbMi value = item["value"];
|
||||||
if (value.isValid()) {
|
if (value.isValid()) {
|
||||||
int encoding = item["valueencoded"].toInt();
|
int encoding = item["valueencoded"].toInt();
|
||||||
setValue(decodeData(value.data(), encoding));
|
setValue(decodeData(value.data(), DebuggerEncoding(encoding)));
|
||||||
} else {
|
} else {
|
||||||
setValueNeeded();
|
setValueNeeded();
|
||||||
}
|
}
|
||||||
@@ -620,7 +620,7 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
|
|||||||
QByteArray key = child["key"].data();
|
QByteArray key = child["key"].data();
|
||||||
if (!key.isEmpty()) {
|
if (!key.isEmpty()) {
|
||||||
int encoding = child["keyencoded"].toInt();
|
int encoding = child["keyencoded"].toInt();
|
||||||
data1.name = decodeData(key, encoding);
|
data1.name = decodeData(key, DebuggerEncoding(encoding));
|
||||||
}
|
}
|
||||||
childHandler(data1, child);
|
childHandler(data1, child);
|
||||||
}
|
}
|
||||||
|
@@ -44,47 +44,6 @@ class DebuggerCommand;
|
|||||||
class DebuggerEngine;
|
class DebuggerEngine;
|
||||||
class WatchModel;
|
class WatchModel;
|
||||||
|
|
||||||
// Special formats. Keep in sync with dumper.py.
|
|
||||||
enum DisplayFormat
|
|
||||||
{
|
|
||||||
AutomaticFormat, // Based on type for individuals, dumper default for types.
|
|
||||||
RawFormat,
|
|
||||||
|
|
||||||
SimpleFormat, // Typical simple format (e.g. for QModelIndex row/column)
|
|
||||||
EnhancedFormat, // Enhanced format (e.g. for QModelIndex with resolved display)
|
|
||||||
SeparateFormat, // Display in separate Window
|
|
||||||
|
|
||||||
Latin1StringFormat,
|
|
||||||
SeparateLatin1StringFormat,
|
|
||||||
Utf8StringFormat,
|
|
||||||
SeparateUtf8StringFormat,
|
|
||||||
Local8BitStringFormat,
|
|
||||||
Utf16StringFormat,
|
|
||||||
Ucs4StringFormat,
|
|
||||||
|
|
||||||
Array10Format,
|
|
||||||
Array100Format,
|
|
||||||
Array1000Format,
|
|
||||||
Array10000Format,
|
|
||||||
ArrayPlotFormat,
|
|
||||||
|
|
||||||
CompactMapFormat,
|
|
||||||
DirectQListStorageFormat,
|
|
||||||
IndirectQListStorageFormat,
|
|
||||||
|
|
||||||
// Not used in *.py.
|
|
||||||
BoolTextFormat,
|
|
||||||
BoolIntegerFormat,
|
|
||||||
|
|
||||||
DecimalIntegerFormat,
|
|
||||||
HexadecimalIntegerFormat,
|
|
||||||
BinaryIntegerFormat,
|
|
||||||
OctalIntegerFormat,
|
|
||||||
|
|
||||||
CompactFloatFormat,
|
|
||||||
ScientificFloatFormat,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef QVector<DisplayFormat> DisplayFormats;
|
typedef QVector<DisplayFormat> DisplayFormats;
|
||||||
|
|
||||||
class WatchItem : public Utils::TreeItem, public WatchData
|
class WatchItem : public Utils::TreeItem, public WatchData
|
||||||
|
Reference in New Issue
Block a user