Commit 9130cdfc authored by hjk's avatar hjk
Browse files

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: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 902db4fa
......@@ -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
......
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