forked from qt-creator/qt-creator
Debugger: Use special values for translatable strings
... when passing data from the dumpers to the GUI. This reduces the need to guess whether a value contains a translatable string. Change-Id: I5e2210b8d028bd71f0087a2ba5c7c5b04331b882 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -41,7 +41,7 @@ def qdump__boost__bimaps__bimap(d, value):
|
||||
|
||||
def qdump__boost__optional(d, value):
|
||||
if int(value["m_initialized"]) == 0:
|
||||
d.putValue("<uninitialized>")
|
||||
d.putSpecialValue(SpecialUninitializedValue)
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
type = d.templateArgument(value.type, 0)
|
||||
|
||||
@@ -129,8 +129,18 @@ Hex2EncodedFloat4, \
|
||||
Hex2EncodedFloat8, \
|
||||
IPv6AddressAndHexScopeId, \
|
||||
Hex2EncodedUtf8WithoutQuotes, \
|
||||
DateTimeInternal \
|
||||
= range(30)
|
||||
DateTimeInternal, \
|
||||
SpecialEmptyValue, \
|
||||
SpecialUninitializedValue, \
|
||||
SpecialInvalidValue, \
|
||||
SpecialNotAccessibleValue, \
|
||||
SpecialItemCountValue, \
|
||||
SpecialMinimumItemCountValue, \
|
||||
SpecialNotCallableValue, \
|
||||
SpecialNullReferenceValue, \
|
||||
SpecialOptimizedOutValue, \
|
||||
SpecialEmptyStructureValue, \
|
||||
= range(40)
|
||||
|
||||
# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
|
||||
StopDisplay, \
|
||||
@@ -292,7 +302,7 @@ class Children:
|
||||
if self.d.passExceptions:
|
||||
showException("CHILDREN", exType, exValue, exTraceBack)
|
||||
self.d.putNumChild(0)
|
||||
self.d.putValue("<not accessible>")
|
||||
self.d.putSpecialValue(SpecialNotAccessibleValue)
|
||||
if not self.d.currentMaxNumChild is None:
|
||||
if self.d.currentMaxNumChild < self.d.currentNumChild:
|
||||
self.d.put('{name="<incomplete>",value="",type="",numchild="0"},')
|
||||
@@ -692,7 +702,7 @@ class DumperBase:
|
||||
self.putItem(result)
|
||||
except:
|
||||
with SubItem(self, name):
|
||||
self.putValue("<not callable>")
|
||||
self.putSpecialValue(SpecialNotCallableValue);
|
||||
self.putNumChild(0)
|
||||
|
||||
def call(self, value, func, *args):
|
||||
@@ -816,9 +826,9 @@ class DumperBase:
|
||||
def putItemCount(self, count, maximum = 1000000000):
|
||||
# This needs to override the default value, so don't use 'put' directly.
|
||||
if count > maximum:
|
||||
self.putValue('<>%s items>' % maximum)
|
||||
self.putSpeciaValue(SpecialMinimumItemCountValue, maximum)
|
||||
else:
|
||||
self.putValue('<%s items>' % count)
|
||||
self.putSpecialValue(SpecialItemCountValue, count)
|
||||
self.putNumChild(count)
|
||||
|
||||
def putField(self, name, value):
|
||||
@@ -837,6 +847,9 @@ class DumperBase:
|
||||
if priority >= self.currentValue.priority:
|
||||
self.currentValue = ReportItem(value, encoding, priority, elided)
|
||||
|
||||
def putSpecialValue(self, encoding, value = ""):
|
||||
self.putValue(value, encoding)
|
||||
|
||||
def putEmptyValue(self, priority = -10):
|
||||
if priority >= self.currentValue.priority:
|
||||
self.currentValue = ReportItem("", None, priority, None)
|
||||
@@ -1413,7 +1426,7 @@ class DumperBase:
|
||||
else:
|
||||
connections = connections.dereference()
|
||||
connections = connections.cast(self.directBaseClass(connections.type))
|
||||
self.putValue('<>0 items>')
|
||||
self.putSpecialValue(SpecialMinimumItemCountValue, 0)
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded():
|
||||
pp = 0
|
||||
|
||||
@@ -465,7 +465,7 @@ class Dumper(DumperBase):
|
||||
if self.passExceptions:
|
||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||
self.putNumChild(0)
|
||||
self.putValue("<not accessible>")
|
||||
self.putSpecialValue(SpecialNotAccessibleValue)
|
||||
try:
|
||||
if self.currentType.value:
|
||||
typeName = self.stripClassTag(self.currentType.value)
|
||||
@@ -473,7 +473,8 @@ class Dumper(DumperBase):
|
||||
self.put('type="%s",' % typeName) # str(type.unqualified()) ?
|
||||
|
||||
if self.currentValue.value is None:
|
||||
self.put('value="<not accessible>",numchild="0",')
|
||||
self.put('value="",encoding="%d","numchild="0",'
|
||||
% SpecialNotAccessibleValue)
|
||||
else:
|
||||
if not self.currentValue.encoding is None:
|
||||
self.put('valueencoded="%d",' % self.currentValue.encoding)
|
||||
@@ -930,7 +931,7 @@ class Dumper(DumperBase):
|
||||
if value is None:
|
||||
# Happens for non-available watchers in gdb versions that
|
||||
# need to use gdb.execute instead of gdb.parse_and_eval
|
||||
self.putValue("<not available>")
|
||||
self.putSpecialValue(SpecialNotAvailableValue)
|
||||
self.putType("<unknown>")
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -939,7 +940,7 @@ class Dumper(DumperBase):
|
||||
typeName = str(typeobj)
|
||||
|
||||
if value.is_optimized_out:
|
||||
self.putValue("<optimized out>")
|
||||
self.putSpecialValue(SpecialOptimizedOutValue)
|
||||
self.putType(typeName)
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -960,7 +961,7 @@ class Dumper(DumperBase):
|
||||
try:
|
||||
# Try to recognize null references explicitly.
|
||||
if toInteger(value.address) == 0:
|
||||
self.putValue("<null reference>")
|
||||
self.putSpecialValue(SpecialNullReferenceValue)
|
||||
self.putType(typeName)
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -988,7 +989,7 @@ class Dumper(DumperBase):
|
||||
self.putBetterType("%s &" % self.currentType.value)
|
||||
return
|
||||
except RuntimeError:
|
||||
self.putValue("<optimized out reference>")
|
||||
self.putSpecialValue(SpecialOptimizedOutValue)
|
||||
self.putType(typeName)
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -1069,7 +1070,7 @@ class Dumper(DumperBase):
|
||||
# Anonymous union. We need a dummy name to distinguish
|
||||
# multiple anonymous unions in the struct.
|
||||
self.putType(typeobj)
|
||||
self.putValue("{...}")
|
||||
self.putSpecialValue(SpecialEmptyStructureValue)
|
||||
self.anonNumber += 1
|
||||
with Children(self, 1):
|
||||
self.listAnonymous(value, "#%d" % self.anonNumber, typeobj)
|
||||
@@ -1706,7 +1707,7 @@ class CliDumper(Dumper):
|
||||
if self.passExceptions:
|
||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||
self.putNumChild(0)
|
||||
self.putValue("<not accessible>")
|
||||
self.putSpecialValue(SpecialNotAccessibleValue)
|
||||
try:
|
||||
if self.currentType.value:
|
||||
typeName = self.stripClassTag(self.currentType.value)
|
||||
|
||||
@@ -266,14 +266,15 @@ class Dumper(DumperBase):
|
||||
if self.passExceptions:
|
||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||
self.putNumChild(0)
|
||||
self.putValue("<not accessible>")
|
||||
self.putSpecialValue(SpecialNotAccessibleValue)
|
||||
try:
|
||||
if self.currentType.value:
|
||||
typeName = self.currentType.value
|
||||
if len(typeName) > 0 and typeName != self.currentChildType:
|
||||
self.put('type="%s",' % typeName) # str(type.unqualified()) ?
|
||||
if self.currentValue.value is None:
|
||||
self.put('value="<not accessible>",numchild="0",')
|
||||
self.put('value="",encoding="%d",numchild="0",'
|
||||
% SpecialNotAccessibleValue)
|
||||
else:
|
||||
if not self.currentValue.encoding is None:
|
||||
self.put('valueencoded="%s",' % self.currentValue.encoding)
|
||||
|
||||
@@ -1552,7 +1552,7 @@ def qdump__QRegExp(d, value):
|
||||
def qdump__QRegion(d, value):
|
||||
p = value["d"].dereference()["qt_rgn"]
|
||||
if d.isNull(p):
|
||||
d.putValue("<empty>")
|
||||
d.putSpecialValue(SpecialEmptyValue)
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
# struct QRegionPrivate:
|
||||
|
||||
@@ -728,6 +728,36 @@ QString decodeData(const QByteArray &ba, int encoding)
|
||||
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>");
|
||||
}
|
||||
case SpecialUninitializedValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<uninitialized>");
|
||||
}
|
||||
case SpecialInvalidValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<invalid>");
|
||||
}
|
||||
case SpecialNotAccessibleValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not accessible>");
|
||||
}
|
||||
case SpecialItemCountValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<%n items>", nullptr, ba.toInt());
|
||||
}
|
||||
case SpecialMinimumItemCountValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<at least %n items>", nullptr, ba.toInt());
|
||||
}
|
||||
case SpecialNotCallableValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not callable>");
|
||||
}
|
||||
case SpecialNullReferenceValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<null reference>");
|
||||
}
|
||||
case SpecialOptimizedOutValue: {
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<optimized out>");
|
||||
}
|
||||
case SpecialEmptyStructureValue: {
|
||||
return QLatin1String("{...}");
|
||||
}
|
||||
}
|
||||
qDebug() << "ENCODING ERROR: " << encoding;
|
||||
return QCoreApplication::translate("Debugger", "<Encoding error>");
|
||||
|
||||
@@ -240,7 +240,17 @@ enum DebuggerEncoding
|
||||
Hex2EncodedFloat8 = 26,
|
||||
IPv6AddressAndHexScopeId = 27,
|
||||
Hex2EncodedUtf8WithoutQuotes = 28,
|
||||
DateTimeInternal = 29
|
||||
DateTimeInternal = 29,
|
||||
SpecialEmptyValue = 30,
|
||||
SpecialUninitializedValue = 31,
|
||||
SpecialInvalidValue = 32,
|
||||
SpecialNotAccessibleValue = 33,
|
||||
SpecialItemCountValue = 34,
|
||||
SpecialMinimumItemCountValue = 35,
|
||||
SpecialNotCallableValue = 36,
|
||||
SpecialNullReferenceValue = 37,
|
||||
SpecialOptimizedOutValue = 38,
|
||||
SpecialEmptyStructureValue = 39
|
||||
};
|
||||
|
||||
// Keep in sync with dumper.py, symbolgroupvalue.cpp of CDB
|
||||
|
||||
@@ -511,34 +511,6 @@ static QString quoteUnprintable(const QString &str)
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static QString translate(const QString &str)
|
||||
{
|
||||
if (str.startsWith(QLatin1Char('<'))) {
|
||||
if (str == QLatin1String("<empty>"))
|
||||
return WatchHandler::tr("<empty>");
|
||||
if (str == QLatin1String("<uninitialized>"))
|
||||
return WatchHandler::tr("<uninitialized>");
|
||||
if (str == QLatin1String("<invalid>"))
|
||||
return WatchHandler::tr("<invalid>");
|
||||
if (str == QLatin1String("<not accessible>"))
|
||||
return WatchHandler::tr("<not accessible>");
|
||||
if (str.endsWith(QLatin1String(" items>"))) {
|
||||
// '<10 items>' or '<>10 items>' (more than)
|
||||
bool ok;
|
||||
const bool moreThan = str.at(1) == QLatin1Char('>');
|
||||
const int numberPos = moreThan ? 2 : 1;
|
||||
const int len = str.indexOf(QLatin1Char(' ')) - numberPos;
|
||||
const int size = str.mid(numberPos, len).toInt(&ok);
|
||||
QTC_ASSERT(ok, qWarning("WatchHandler: Invalid item count '%s'",
|
||||
qPrintable(str)));
|
||||
return moreThan ?
|
||||
WatchHandler::tr("<more than %n items>", 0, size) :
|
||||
WatchHandler::tr("<%n items>", 0, size);
|
||||
}
|
||||
}
|
||||
return quoteUnprintable(str);
|
||||
}
|
||||
|
||||
QString WatchItem::formattedValue() const
|
||||
{
|
||||
if (type == "bool") {
|
||||
@@ -594,12 +566,11 @@ QString WatchItem::formattedValue() const
|
||||
if (elided) {
|
||||
QString v = value;
|
||||
v.chop(1);
|
||||
v = translate(v);
|
||||
QString len = elided > 0 ? QString::number(elided) : QLatin1String("unknown length");
|
||||
return v + QLatin1String("\"... (") + len + QLatin1Char(')');
|
||||
}
|
||||
|
||||
return translate(value);
|
||||
return quoteUnprintable(value);
|
||||
}
|
||||
|
||||
// Get a pointer address from pointer values reported by the debugger.
|
||||
@@ -657,7 +628,7 @@ QVariant WatchItem::editValue() const
|
||||
stringValue.replace(QLatin1String("\n"), QLatin1String("\\n"));
|
||||
}
|
||||
}
|
||||
return QVariant(translate(stringValue));
|
||||
return QVariant(quoteUnprintable(stringValue));
|
||||
}
|
||||
|
||||
bool WatchItem::canFetchMore() const
|
||||
|
||||
Reference in New Issue
Block a user