Commit eca5ccdd authored by hjk's avatar hjk
Browse files

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: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent fb387ea2
......@@ -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
......
Markdown is supported
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