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)
|
||||
|
||||
|
||||
# Known special formats. Keep in sync with DisplayFormat in watchhandler.h
|
||||
# Known special formats. Keep in sync with DisplayFormat in debuggerprotocol.h
|
||||
AutomaticFormat, \
|
||||
RawFormat, \
|
||||
SimpleFormat, \
|
||||
@@ -142,7 +142,7 @@ SpecialOptimizedOutValue, \
|
||||
SpecialEmptyStructureValue, \
|
||||
= range(40)
|
||||
|
||||
# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
|
||||
# Display modes. Keep that synchronized with DebuggerDisplay in debuggerprotocol.h
|
||||
StopDisplay, \
|
||||
DisplayImageData, \
|
||||
DisplayUtf16String, \
|
||||
|
@@ -558,7 +558,7 @@ static void getDateTime(qint64 msecs, int status, QDate *date, QTime *time)
|
||||
*time = (status & NullTime) ? QTime() : QTime::fromMSecsSinceStartOfDay(ds);
|
||||
}
|
||||
|
||||
QString decodeData(const QByteArray &ba, int encoding)
|
||||
QString decodeData(const QByteArray &ba, DebuggerEncoding encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
case Unencoded8Bit: // 0
|
||||
@@ -657,17 +657,39 @@ QString decodeData(const QByteArray &ba, int encoding)
|
||||
const QDate date = dateFromData(ba.toInt());
|
||||
return date.isValid() ? date.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
||||
}
|
||||
case MillisecondsSinceMidnight: {
|
||||
case MillisecondsSinceMidnight: { // 15
|
||||
const QTime time = timeFromData(ba.toInt());
|
||||
return time.isValid() ? time.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
||||
}
|
||||
case JulianDateAndMillisecondsSinceMidnight: {
|
||||
case JulianDateAndMillisecondsSinceMidnight: { // 16
|
||||
const int p = ba.indexOf('/');
|
||||
const QDate date = dateFromData(ba.left(p).toInt());
|
||||
const QTime time = timeFromData(ba.mid(p + 1 ).toInt());
|
||||
const QDateTime dateTime = QDateTime(date, time);
|
||||
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
|
||||
const int p = ba.indexOf('%');
|
||||
QHostAddress ip6(QString::fromLatin1(p == -1 ? ba : ba.left(p)));
|
||||
@@ -716,46 +738,34 @@ QString decodeData(const QByteArray &ba, int encoding)
|
||||
}
|
||||
return dateTime.toString();
|
||||
}
|
||||
case Hex2EncodedFloat4: {
|
||||
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: {
|
||||
case SpecialEmptyValue: { // 30
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<empty>");
|
||||
}
|
||||
case SpecialUninitializedValue: {
|
||||
case SpecialUninitializedValue: { // 31
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<uninitialized>");
|
||||
}
|
||||
case SpecialInvalidValue: {
|
||||
case SpecialInvalidValue: { // 32
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<invalid>");
|
||||
}
|
||||
case SpecialNotAccessibleValue: {
|
||||
case SpecialNotAccessibleValue: { // 33
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not accessible>");
|
||||
}
|
||||
case SpecialItemCountValue: {
|
||||
case SpecialItemCountValue: { // 34
|
||||
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());
|
||||
}
|
||||
case SpecialNotCallableValue: {
|
||||
case SpecialNotCallableValue: { // 36
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not callable>");
|
||||
}
|
||||
case SpecialNullReferenceValue: {
|
||||
case SpecialNullReferenceValue: { // 37
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<null reference>");
|
||||
}
|
||||
case SpecialOptimizedOutValue: {
|
||||
case SpecialOptimizedOutValue: { // 38
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<optimized out>");
|
||||
}
|
||||
case SpecialEmptyStructureValue: {
|
||||
case SpecialEmptyStructureValue: { // 39
|
||||
return QLatin1String("{...}");
|
||||
}
|
||||
}
|
||||
|
@@ -208,7 +208,13 @@ public:
|
||||
void extractGdbVersion(const QString &msg,
|
||||
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
|
||||
|
||||
enum DebuggerEncoding
|
||||
{
|
||||
Unencoded8Bit = 0,
|
||||
@@ -253,8 +259,68 @@ enum DebuggerEncoding
|
||||
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
|
||||
enum DebuggerDisplay {
|
||||
enum DebuggerDisplay
|
||||
{
|
||||
StopDisplay = 0,
|
||||
DisplayImageData = 1,
|
||||
DisplayUtf16String = 2,
|
||||
@@ -263,8 +329,6 @@ enum DebuggerDisplay {
|
||||
DisplayUtf8String = 5,
|
||||
DisplayPlotData = 6
|
||||
};
|
||||
// Decode string data as returned by the dumper helpers.
|
||||
QString decodeData(const QByteArray &baIn, int encoding);
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
@@ -3498,7 +3498,7 @@ void GdbEngine::handleThreadNames(const DebuggerResponse &response)
|
||||
ThreadData thread;
|
||||
thread.id = ThreadId(name["id"].toInt());
|
||||
thread.name = decodeData(name["value"].data(),
|
||||
name["valueencoded"].toInt());
|
||||
DebuggerEncoding(name["valueencoded"].toInt()));
|
||||
handler->updateThread(thread);
|
||||
}
|
||||
updateViews();
|
||||
|
@@ -393,7 +393,7 @@ void WatchData::updateValue(const GdbMi &item)
|
||||
GdbMi value = item["value"];
|
||||
if (value.isValid()) {
|
||||
int encoding = item["valueencoded"].toInt();
|
||||
setValue(decodeData(value.data(), encoding));
|
||||
setValue(decodeData(value.data(), DebuggerEncoding(encoding)));
|
||||
} else {
|
||||
setValueNeeded();
|
||||
}
|
||||
@@ -620,7 +620,7 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
|
||||
QByteArray key = child["key"].data();
|
||||
if (!key.isEmpty()) {
|
||||
int encoding = child["keyencoded"].toInt();
|
||||
data1.name = decodeData(key, encoding);
|
||||
data1.name = decodeData(key, DebuggerEncoding(encoding));
|
||||
}
|
||||
childHandler(data1, child);
|
||||
}
|
||||
|
@@ -44,47 +44,6 @@ class DebuggerCommand;
|
||||
class DebuggerEngine;
|
||||
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;
|
||||
|
||||
class WatchItem : public Utils::TreeItem, public WatchData
|
||||
|
Reference in New Issue
Block a user