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):
|
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, \
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
# 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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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)
|
|||||||
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
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user