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