forked from qt-creator/qt-creator
Debugger: Split DebuggerEncoding enum
... into a string specifying a kind of encoding (utf8, latin1), an optional bytesize (2-byte integers, 4-byte integers) and a flag whether the displayed value should get "..." around it. Scales better than adding an enum value for each new combination. Change-Id: Iffcb1e2f148f12da96e165559a976bd34026c649 Reviewed-by: David Schulz <david.schulz@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.putSpecialValue(SpecialUninitializedValue)
|
||||
d.putSpecialValue("uninitialized")
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
type = d.templateArgument(value.type, 0)
|
||||
@@ -114,18 +114,18 @@ def qdump__boost__container__list(d, value):
|
||||
|
||||
|
||||
def qdump__boost__gregorian__date(d, value):
|
||||
d.putValue(int(value["days_"]), JulianDate)
|
||||
d.putValue(int(value["days_"]), "juliandate")
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
def qdump__boost__posix_time__ptime(d, value):
|
||||
ms = int(int(value["time_"]["time_count_"]["value_"]) / 1000)
|
||||
d.putValue("%s/%s" % divmod(ms, 86400000), JulianDateAndMillisecondsSinceMidnight)
|
||||
d.putValue("%s/%s" % divmod(ms, 86400000), "juliandateandmillisecondssincemidnight")
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
def qdump__boost__posix_time__time_duration(d, value):
|
||||
d.putValue(int(int(value["ticks_"]["value_"]) / 1000), MillisecondsSinceMidnight)
|
||||
d.putValue(int(int(value["ticks_"]["value_"]) / 1000), "millisecondssincemidnight")
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ def readLiteral(d, value):
|
||||
return "<unsupported>"
|
||||
|
||||
def dumpLiteral(d, value):
|
||||
d.putValue(d.hexencode(readLiteral(d, value)), Hex2EncodedLatin1)
|
||||
d.putValue(d.hexencode(readLiteral(d, value)), "latin1")
|
||||
|
||||
def qdump__Core__Id(d, value):
|
||||
try:
|
||||
@@ -104,7 +104,7 @@ def qdump__Core__Id(d, value):
|
||||
def qdump__Debugger__Internal__GdbMi(d, value):
|
||||
str = d.encodeByteArray(value["m_name"]) + "3a20" \
|
||||
+ d.encodeByteArray(value["m_data"])
|
||||
d.putValue(str, Hex2EncodedLatin1)
|
||||
d.putValue(str, "latin1")
|
||||
d.putPlainChildren(value)
|
||||
|
||||
def qdump__Debugger__Internal__DisassemblerLine(d, value):
|
||||
@@ -153,7 +153,7 @@ def qdump__CPlusPlus__FullySpecifiedType(d, value):
|
||||
if typeName == "CPlusPlus::NamedType":
|
||||
dumpLiteral(d, type["_name"])
|
||||
elif typeName == "CPlusPlus::PointerType":
|
||||
d.putValue(d.hexencode(extractPointerType(d, type)), Hex2EncodedLatin1)
|
||||
d.putValue(d.hexencode(extractPointerType(d, type)), "latin1")
|
||||
d.putPlainChildren(value)
|
||||
|
||||
def qdump__CPlusPlus__NamedType(d, value):
|
||||
@@ -162,7 +162,7 @@ def qdump__CPlusPlus__NamedType(d, value):
|
||||
d.putPlainChildren(value)
|
||||
|
||||
def qdump__CPlusPlus__PointerType(d, value):
|
||||
d.putValue(d.hexencode(extractPointerType(d, value)), Hex2EncodedLatin1)
|
||||
d.putValue(d.hexencode(extractPointerType(d, value)), "latin1")
|
||||
d.putPlainChildren(value)
|
||||
|
||||
def qdump__CPlusPlus__TemplateNameId(d, value):
|
||||
@@ -214,8 +214,7 @@ def qdump__CPlusPlus__Internal__PPToken(d, value):
|
||||
offset = int(value["utf16charOffset"])
|
||||
#warn("size: %s, alloc: %s, offset: %s, length: %s, data: %s"
|
||||
# % (size, alloc, offset, length, data))
|
||||
d.putValue(d.readMemory(data + offset, min(100, length)),
|
||||
Hex2EncodedLatin1)
|
||||
d.putValue(d.readMemory(data + offset, min(100, length)), "latin1")
|
||||
d.putPlainChildren(value)
|
||||
|
||||
def qdump__ProString(d, value):
|
||||
@@ -225,7 +224,7 @@ def qdump__ProString(d, value):
|
||||
data += 2 * int(value["m_offset"])
|
||||
size = int(value["m_length"])
|
||||
s = d.readMemory(data, 2 * size)
|
||||
d.putValue(s, Hex4EncodedLittleEndian)
|
||||
d.putValue(s, "utf16")
|
||||
except:
|
||||
d.putEmptyValue()
|
||||
d.putPlainChildren(value)
|
||||
|
||||
@@ -99,49 +99,6 @@ BreakpointOnQmlSignalEmit, \
|
||||
BreakpointAtJavaScriptThrow, \
|
||||
= range(0, 14)
|
||||
|
||||
# Encodings. Keep that synchronized with DebuggerEncoding in debuggerprotocol.h
|
||||
Unencoded8Bit, \
|
||||
Base64Encoded8BitWithQuotes, \
|
||||
Base64Encoded16BitWithQuotes, \
|
||||
Base64Encoded32BitWithQuotes, \
|
||||
Base64Encoded16Bit, \
|
||||
Base64Encoded8Bit, \
|
||||
Hex2EncodedLatin1, \
|
||||
Hex4EncodedLittleEndian, \
|
||||
Hex8EncodedLittleEndian, \
|
||||
Hex2EncodedUtf8, \
|
||||
Hex8EncodedBigEndian, \
|
||||
Hex4EncodedBigEndian, \
|
||||
Hex4EncodedLittleEndianWithoutQuotes, \
|
||||
Hex2EncodedLocal8Bit, \
|
||||
JulianDate, \
|
||||
MillisecondsSinceMidnight, \
|
||||
JulianDateAndMillisecondsSinceMidnight, \
|
||||
Hex2EncodedInt1, \
|
||||
Hex2EncodedInt2, \
|
||||
Hex2EncodedInt4, \
|
||||
Hex2EncodedInt8, \
|
||||
Hex2EncodedUInt1, \
|
||||
Hex2EncodedUInt2, \
|
||||
Hex2EncodedUInt4, \
|
||||
Hex2EncodedUInt8, \
|
||||
Hex2EncodedFloat4, \
|
||||
Hex2EncodedFloat8, \
|
||||
IPv6AddressAndHexScopeId, \
|
||||
Hex2EncodedUtf8WithoutQuotes, \
|
||||
DateTimeInternal, \
|
||||
SpecialEmptyValue, \
|
||||
SpecialUninitializedValue, \
|
||||
SpecialInvalidValue, \
|
||||
SpecialNotAccessibleValue, \
|
||||
SpecialItemCountValue, \
|
||||
SpecialMinimumItemCountValue, \
|
||||
SpecialNotCallableValue, \
|
||||
SpecialNullReferenceValue, \
|
||||
SpecialOptimizedOutValue, \
|
||||
SpecialEmptyStructureValue, \
|
||||
= range(40)
|
||||
|
||||
# Display modes. Keep that synchronized with DebuggerDisplay in debuggerprotocol.h
|
||||
StopDisplay, \
|
||||
DisplayImageData, \
|
||||
@@ -302,7 +259,7 @@ class Children:
|
||||
if self.d.passExceptions:
|
||||
showException("CHILDREN", exType, exValue, exTraceBack)
|
||||
self.d.putNumChild(0)
|
||||
self.d.putSpecialValue(SpecialNotAccessibleValue)
|
||||
self.d.putSpecialValue("notaccessible")
|
||||
if not self.d.currentMaxNumChild is None:
|
||||
if self.d.currentMaxNumChild < self.d.currentNumChild:
|
||||
self.d.put('{name="<incomplete>",value="",type="",numchild="0"},')
|
||||
@@ -578,15 +535,18 @@ class DumperBase:
|
||||
if charSize == 1:
|
||||
if displayFormat == Latin1StringFormat \
|
||||
or displayFormat == SeparateLatin1StringFormat:
|
||||
encodingType = Hex2EncodedLatin1
|
||||
encodingType = "latin1"
|
||||
else:
|
||||
encodingType = Hex2EncodedUtf8
|
||||
encodingType = "utf8"
|
||||
childType = "char"
|
||||
displayType = DisplayLatin1String
|
||||
elif charSize == 2:
|
||||
encodingType = Hex4EncodedLittleEndian
|
||||
encodingType = "utf16"
|
||||
childType = "short"
|
||||
displayType = DisplayUtf16String
|
||||
else:
|
||||
encodingType = Hex8EncodedLittleEndian
|
||||
encodingType = "ucs4"
|
||||
childType = "int"
|
||||
displayType = DisplayUtf16String
|
||||
|
||||
self.putValue(mem, encodingType, elided=elided)
|
||||
@@ -617,7 +577,7 @@ class DumperBase:
|
||||
|
||||
def putByteArrayValue(self, value):
|
||||
elided, data = self.encodeByteArrayHelper(self.extractPointer(value), self.displayStringLimit)
|
||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||
self.putValue(data, "latin1", elided=elided)
|
||||
|
||||
def encodeString(self, value, limit = 0):
|
||||
elided, data = self.encodeStringHelper(self.extractPointer(value), limit)
|
||||
@@ -676,13 +636,13 @@ class DumperBase:
|
||||
|
||||
def putStringValueByAddress(self, addr):
|
||||
elided, data = self.encodeStringHelper(addr, self.displayStringLimit)
|
||||
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
||||
self.putValue(data, "utf16", elided=elided)
|
||||
|
||||
def putStringValue(self, value):
|
||||
elided, data = self.encodeStringHelper(
|
||||
self.extractPointer(value),
|
||||
self.displayStringLimit)
|
||||
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
||||
self.putValue(data, "utf16", elided=elided)
|
||||
|
||||
def putAddressItem(self, name, value, type = ""):
|
||||
with SubItem(self, name):
|
||||
@@ -715,7 +675,7 @@ class DumperBase:
|
||||
self.putItem(result)
|
||||
except:
|
||||
with SubItem(self, name):
|
||||
self.putSpecialValue(SpecialNotCallableValue);
|
||||
self.putSpecialValue("notcallable");
|
||||
self.putNumChild(0)
|
||||
|
||||
def call(self, value, func, *args):
|
||||
@@ -737,22 +697,18 @@ class DumperBase:
|
||||
ns = self.qtNamespace()
|
||||
typeName = self.stripClassTag(str(value.type))
|
||||
if typeName == ns + "QString":
|
||||
self.put('key="%s",' % self.encodeString(value))
|
||||
self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
|
||||
self.put('keyencoded="utf16:2:0",key="%s",' % self.encodeString(value))
|
||||
elif typeName == ns + "QByteArray":
|
||||
self.put('key="%s",' % self.encodeByteArray(value))
|
||||
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
|
||||
self.put('keyencoded="latin1:1:0",key="%s",' % self.encodeByteArray(value))
|
||||
elif typeName == "std::string":
|
||||
self.put('key="%s",' % self.encodeStdString(value))
|
||||
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
|
||||
self.put('keyencoded="latin1:1:0",key="%s",' % self.encodeStdString(value))
|
||||
else:
|
||||
val = str(value.GetValue()) if self.isLldb else str(value)
|
||||
if index is None:
|
||||
key = '%s' % val
|
||||
else:
|
||||
key = '[%s] %s' % (index, val)
|
||||
self.put('key="%s",' % self.hexencode(key))
|
||||
self.put('keyencoded="%s",' % Hex2EncodedUtf8WithoutQuotes)
|
||||
self.put('keyencoded="utf8:1:0",key="%s",' % self.hexencode(key))
|
||||
|
||||
def putPair(self, pair, index = None):
|
||||
if self.pairData.useKeyAndValue:
|
||||
@@ -763,14 +719,11 @@ class DumperBase:
|
||||
value = pair["second"]
|
||||
if self.pairData.isCompact:
|
||||
if self.pairData.keyIsQString:
|
||||
self.put('key="%s",' % self.encodeString(key))
|
||||
self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
|
||||
self.put('keyencoded="utf16",key="%s",' % self.encodeString(key))
|
||||
elif self.pairData.keyIsQByteArray:
|
||||
self.put('key="%s",' % self.encodeByteArray(key))
|
||||
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
|
||||
self.put('keyencoded="latin1",key="%s",' % self.encodeByteArray(key))
|
||||
elif self.pairData.keyIsStdString:
|
||||
self.put('key="%s",' % self.encodeStdString(key))
|
||||
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
|
||||
self.put('keyencoded="latin1",key="%s",' % self.encodeStdString(key))
|
||||
else:
|
||||
name = str(key.GetValue()) if self.isLldb else str(key)
|
||||
if index == -1:
|
||||
@@ -833,9 +786,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.putSpecialValue(SpecialMinimumItemCountValue, maximum)
|
||||
self.putSpecialValue("minimumitemcount", maximum)
|
||||
else:
|
||||
self.putSpecialValue(SpecialItemCountValue, count)
|
||||
self.putSpecialValue("itemcount", count)
|
||||
self.putNumChild(count)
|
||||
|
||||
def resultToMi(self, value):
|
||||
@@ -1082,7 +1035,7 @@ class DumperBase:
|
||||
else:
|
||||
elided, shown = self.computeLimit(int(size), self.displayStringLimit)
|
||||
data = self.readMemory(base, shown)
|
||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||
self.putValue(data, "latin1", elided=elided)
|
||||
|
||||
def putDisplay(self, editFormat, value):
|
||||
self.put('editformat="%s",' % editFormat)
|
||||
@@ -1094,51 +1047,51 @@ class DumperBase:
|
||||
# Use Latin1 as default for char *.
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||
self.putValue(data, "latin1", elided=elided)
|
||||
return True
|
||||
|
||||
if displayFormat == Latin1StringFormat:
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||
self.putValue(data, "latin1", elided=elided)
|
||||
return True
|
||||
|
||||
if displayFormat == SeparateLatin1StringFormat:
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||
self.putValue(data, "latin1", elided=elided)
|
||||
self.putDisplay(DisplayLatin1String, data)
|
||||
return True
|
||||
|
||||
if displayFormat == Utf8StringFormat:
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||
self.putValue(data, Hex2EncodedUtf8, elided=elided)
|
||||
self.putValue(data, "utf8", elided=elided)
|
||||
return True
|
||||
|
||||
if displayFormat == SeparateUtf8StringFormat:
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||
self.putValue(data, Hex2EncodedUtf8, elided=elided)
|
||||
self.putValue(data, "utf8", elided=elided)
|
||||
self.putDisplay(DisplayUtf8String, data)
|
||||
return True
|
||||
|
||||
if displayFormat == Local8BitStringFormat:
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||
self.putValue(data, Hex2EncodedLocal8Bit, elided=elided)
|
||||
self.putValue(data, "local8bit", elided=elided)
|
||||
return True
|
||||
|
||||
if displayFormat == Utf16StringFormat:
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 2, limit)
|
||||
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
||||
self.putValue(data, "utf16", elided=elided)
|
||||
return True
|
||||
|
||||
if displayFormat == Ucs4StringFormat:
|
||||
self.putType(typeName)
|
||||
(elided, data) = self.encodeCArray(value, 4, limit)
|
||||
self.putValue(data, Hex8EncodedLittleEndian, elided=elided)
|
||||
self.putValue(data, "ucs4", elided=elided)
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -1176,7 +1129,7 @@ class DumperBase:
|
||||
if displayFormat == RawFormat:
|
||||
# Explicitly requested bald pointer.
|
||||
self.putType(typeName)
|
||||
self.putValue(self.hexencode(str(value)), Hex2EncodedUtf8WithoutQuotes)
|
||||
self.putValue(self.hexencode(str(value)), "utf8:1:0")
|
||||
self.putNumChild(1)
|
||||
if self.currentIName in self.expandedINames:
|
||||
with Children(self):
|
||||
@@ -1293,7 +1246,7 @@ class DumperBase:
|
||||
return False
|
||||
|
||||
raw = self.readMemory(data, 2 * size)
|
||||
self.putValue(raw, Hex4EncodedLittleEndian, 1)
|
||||
self.putValue(raw, "utf16", 1)
|
||||
return True
|
||||
|
||||
except:
|
||||
@@ -1490,7 +1443,7 @@ class DumperBase:
|
||||
for (k, v) in zip(names, values):
|
||||
with SubItem(self, propertyCount):
|
||||
self.put('key="%s",' % self.encodeByteArray(k))
|
||||
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
|
||||
self.put('keyencoded="latin1",')
|
||||
self.putItem(v)
|
||||
propertyCount += 1
|
||||
|
||||
@@ -1536,7 +1489,7 @@ class DumperBase:
|
||||
else:
|
||||
connections = connections.dereference()
|
||||
connections = connections.cast(self.directBaseClass(connections.type))
|
||||
self.putSpecialValue(SpecialMinimumItemCountValue, 0)
|
||||
self.putSpecialValue("minimumitemcount", 0)
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded():
|
||||
pp = 0
|
||||
|
||||
@@ -464,7 +464,7 @@ class Dumper(DumperBase):
|
||||
if self.passExceptions:
|
||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||
self.putNumChild(0)
|
||||
self.putSpecialValue(SpecialNotAccessibleValue)
|
||||
self.putSpecialValue("notaccessible")
|
||||
try:
|
||||
if self.currentType.value:
|
||||
typeName = self.stripClassTag(self.currentType.value)
|
||||
@@ -472,11 +472,10 @@ class Dumper(DumperBase):
|
||||
self.put('type="%s",' % typeName) # str(type.unqualified()) ?
|
||||
|
||||
if self.currentValue.value is None:
|
||||
self.put('value="",encoding="%d",numchild="0",'
|
||||
% SpecialNotAccessibleValue)
|
||||
self.put('value="",encoding="notaccessible",numchild="0",')
|
||||
else:
|
||||
if not self.currentValue.encoding is None:
|
||||
self.put('valueencoded="%d",' % self.currentValue.encoding)
|
||||
self.put('valueencoded="%s",' % self.currentValue.encoding)
|
||||
if self.currentValue.elided:
|
||||
self.put('valueelided="%d",' % self.currentValue.elided)
|
||||
self.put('value="%s",' % self.currentValue.value)
|
||||
@@ -898,31 +897,14 @@ class Dumper(DumperBase):
|
||||
def simpleEncoding(self, typeobj):
|
||||
code = typeobj.code
|
||||
if code == BoolCode or code == CharCode:
|
||||
return Hex2EncodedInt1
|
||||
return "int:1"
|
||||
if code == IntCode:
|
||||
if str(typeobj).find("unsigned") >= 0:
|
||||
if typeobj.sizeof == 1:
|
||||
return Hex2EncodedUInt1
|
||||
if typeobj.sizeof == 2:
|
||||
return Hex2EncodedUInt2
|
||||
if typeobj.sizeof == 4:
|
||||
return Hex2EncodedUInt4
|
||||
if typeobj.sizeof == 8:
|
||||
return Hex2EncodedUInt8
|
||||
return "uint:%d" % typeobj.sizeof
|
||||
else:
|
||||
if typeobj.sizeof == 1:
|
||||
return Hex2EncodedInt1
|
||||
if typeobj.sizeof == 2:
|
||||
return Hex2EncodedInt2
|
||||
if typeobj.sizeof == 4:
|
||||
return Hex2EncodedInt4
|
||||
if typeobj.sizeof == 8:
|
||||
return Hex2EncodedInt8
|
||||
return "int:%d" % typeobj.sizeof
|
||||
if code == FloatCode:
|
||||
if typeobj.sizeof == 4:
|
||||
return Hex2EncodedFloat4
|
||||
if typeobj.sizeof == 8:
|
||||
return Hex2EncodedFloat8
|
||||
return "float:%d" % typeobj.sizeof
|
||||
return None
|
||||
|
||||
def isReferenceType(self, typeobj):
|
||||
@@ -938,7 +920,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.putSpecialValue(SpecialNotAvailableValue)
|
||||
self.putSpecialValue("notaccessible")
|
||||
self.putType("<unknown>")
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -947,7 +929,7 @@ class Dumper(DumperBase):
|
||||
typeName = str(typeobj)
|
||||
|
||||
if value.is_optimized_out:
|
||||
self.putSpecialValue(SpecialOptimizedOutValue)
|
||||
self.putSpecialValue("optimizedout")
|
||||
self.putType(typeName)
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -968,7 +950,7 @@ class Dumper(DumperBase):
|
||||
try:
|
||||
# Try to recognize null references explicitly.
|
||||
if toInteger(value.address) == 0:
|
||||
self.putSpecialValue(SpecialNullReferenceValue)
|
||||
self.putSpecialValue("nullreference")
|
||||
self.putType(typeName)
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -996,7 +978,7 @@ class Dumper(DumperBase):
|
||||
self.putBetterType("%s &" % self.currentType.value)
|
||||
return
|
||||
except RuntimeError:
|
||||
self.putSpecialValue(SpecialOptimizedOutValue)
|
||||
self.putSpecialValue("optimizedout")
|
||||
self.putType(typeName)
|
||||
self.putNumChild(0)
|
||||
return
|
||||
@@ -1077,7 +1059,7 @@ class Dumper(DumperBase):
|
||||
# Anonymous union. We need a dummy name to distinguish
|
||||
# multiple anonymous unions in the struct.
|
||||
self.putType(typeobj)
|
||||
self.putSpecialValue(SpecialEmptyStructureValue)
|
||||
self.putSpecialValue("emptystructure")
|
||||
self.anonNumber += 1
|
||||
with Children(self, 1):
|
||||
self.listAnonymous(value, "#%d" % self.anonNumber, typeobj)
|
||||
@@ -1087,7 +1069,7 @@ class Dumper(DumperBase):
|
||||
# FORTRAN strings
|
||||
size = typeobj.sizeof
|
||||
data = self.readMemory(value.address, size)
|
||||
self.putValue(data, Hex2EncodedLatin1, 1)
|
||||
self.putValue(data, "latin1", 1)
|
||||
self.putType(typeobj)
|
||||
|
||||
if typeobj.code != StructCode and typeobj.code != UnionCode:
|
||||
@@ -1336,8 +1318,7 @@ class Dumper(DumperBase):
|
||||
# s = self.readMemory(data, 2 * size)
|
||||
#
|
||||
# thread = gdb.selected_thread()
|
||||
# inner = '{valueencoded="';
|
||||
# inner += str(Hex4EncodedLittleEndianWithoutQuotes)+'",id="'
|
||||
# inner = '{valueencoded="uf16:2:0",id="'
|
||||
# inner += str(thread.num) + '",value="'
|
||||
# inner += s
|
||||
# #inner += self.encodeString(objectName)
|
||||
@@ -1748,7 +1729,7 @@ class CliDumper(Dumper):
|
||||
if self.passExceptions:
|
||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||
self.putNumChild(0)
|
||||
self.putSpecialValue(SpecialNotAccessibleValue)
|
||||
self.putSpecialValue("notaccessible")
|
||||
try:
|
||||
if self.currentType.value:
|
||||
typeName = self.stripClassTag(self.currentType.value)
|
||||
@@ -1758,11 +1739,11 @@ class CliDumper(Dumper):
|
||||
self.put('<not accessible>')
|
||||
else:
|
||||
value = self.currentValue.value
|
||||
if self.currentValue.encoding is Hex2EncodedLatin1:
|
||||
if self.currentValue.encoding == "latin1":
|
||||
value = self.hexdecode(value)
|
||||
elif self.currentValue.encoding is Hex2EncodedUtf8:
|
||||
elif self.currentValue.encoding == "utf8":
|
||||
value = self.hexdecode(value)
|
||||
elif self.currentValue.encoding is Hex4EncodedLittleEndian:
|
||||
elif self.currentValue.encoding == "utf16":
|
||||
b = bytes.fromhex(value)
|
||||
value = codecs.decode(b, 'utf-16')
|
||||
self.put('"%s"' % value)
|
||||
|
||||
@@ -266,15 +266,14 @@ class Dumper(DumperBase):
|
||||
if self.passExceptions:
|
||||
showException("SUBITEM", exType, exValue, exTraceBack)
|
||||
self.putNumChild(0)
|
||||
self.putSpecialValue(SpecialNotAccessibleValue)
|
||||
self.putSpecialValue("notaccessible")
|
||||
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="",encoding="%d",numchild="0",'
|
||||
% SpecialNotAccessibleValue)
|
||||
self.put('value="",encoding="notaccessible",numchild="0",')
|
||||
else:
|
||||
if not self.currentValue.encoding is None:
|
||||
self.put('valueencoded="%s",' % self.currentValue.encoding)
|
||||
@@ -571,28 +570,14 @@ class Dumper(DumperBase):
|
||||
size = typeobj.sizeof
|
||||
if code == lldb.eTypeClassBuiltin:
|
||||
name = str(typeobj)
|
||||
if name == "float":
|
||||
return Hex2EncodedFloat4
|
||||
if name == "double":
|
||||
return Hex2EncodedFloat8
|
||||
if name.find("unsigned") >= 0:
|
||||
if size == 1:
|
||||
return Hex2EncodedUInt1
|
||||
if size == 2:
|
||||
return Hex2EncodedUInt2
|
||||
if size == 4:
|
||||
return Hex2EncodedUInt4
|
||||
if size == 8:
|
||||
return Hex2EncodedUInt8
|
||||
if name == 'float':
|
||||
return 'float:4'
|
||||
if name == 'double':
|
||||
return 'float:8'
|
||||
if name.find('unsigned') >= 0:
|
||||
return 'uint:%d' % size
|
||||
else:
|
||||
if size == 1:
|
||||
return Hex2EncodedInt1
|
||||
if size == 2:
|
||||
return Hex2EncodedInt2
|
||||
if size == 4:
|
||||
return Hex2EncodedInt4
|
||||
if size == 8:
|
||||
return Hex2EncodedInt8
|
||||
return 'int:%d' % size
|
||||
return None
|
||||
|
||||
def createPointerValue(self, address, pointeeType):
|
||||
|
||||
@@ -178,7 +178,7 @@ def qdump_Array(d, value):
|
||||
t = cleanDType(value.type)[7:]
|
||||
d.putType("%s[%d]" % (t, n))
|
||||
if t == "char":
|
||||
d.putValue(encodeCharArray(p, 100), Hex2EncodedLocal8Bit)
|
||||
d.putValue(encodeCharArray(p, 100), "local8bit")
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
d.putEmptyValue()
|
||||
|
||||
@@ -1537,19 +1537,19 @@ class Dumper:
|
||||
v = value
|
||||
self.putType(tt)
|
||||
self.putValue(self.hexencode(v))
|
||||
self.putField("valueencoded", 6)
|
||||
self.putField("valueencoded", "utf8")
|
||||
self.putNumChild(0)
|
||||
elif tt == "unicode":
|
||||
v = value
|
||||
self.putType(tt)
|
||||
self.putValue(self.hexencode(v))
|
||||
self.putField("valueencoded", 6)
|
||||
self.putField("valueencoded", "utf8")
|
||||
self.putNumChild(0)
|
||||
elif tt == "buffer":
|
||||
v = str(value)
|
||||
self.putType(tt)
|
||||
self.putValue(self.hexencode(v))
|
||||
self.putField("valueencoded", 6)
|
||||
self.putField("valueencoded", "latin1")
|
||||
self.putNumChild(0)
|
||||
elif tt == "xrange":
|
||||
b = iter(value).next()
|
||||
|
||||
@@ -63,15 +63,15 @@ def qdump__QByteArray(d, value):
|
||||
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
|
||||
displayFormat = d.currentItemFormat()
|
||||
if displayFormat == AutomaticFormat or displayFormat == Latin1StringFormat:
|
||||
d.putValue(p, Hex2EncodedLatin1, elided=elided)
|
||||
d.putValue(p, "latin1", elided=elided)
|
||||
elif displayFormat == SeparateLatin1StringFormat:
|
||||
d.putValue(p, Hex2EncodedLatin1, elided=elided)
|
||||
d.putValue(p, "latin1", elided=elided)
|
||||
d.putField("editformat", DisplayLatin1String)
|
||||
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
|
||||
elif displayFormat == Utf8StringFormat:
|
||||
d.putValue(p, Hex2EncodedUtf8, elided=elided)
|
||||
d.putValue(p, "utf8", elided=elided)
|
||||
elif displayFormat == SeparateUtf8StringFormat:
|
||||
d.putValue(p, Hex2EncodedUtf8, elided=elided)
|
||||
d.putValue(p, "utf8", elided=elided)
|
||||
d.putField("editformat", DisplayUtf8String)
|
||||
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
|
||||
if d.isExpanded():
|
||||
@@ -80,7 +80,7 @@ def qdump__QByteArray(d, value):
|
||||
def qdump__QByteArrayData(d, value):
|
||||
data, size, alloc = d.byteArrayDataHelper(d.addressOf(value))
|
||||
d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000))
|
||||
d.putValue(d.readMemory(data, size), Hex2EncodedLatin1)
|
||||
d.putValue(d.readMemory(data, size), "latin1")
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
@@ -195,7 +195,7 @@ def qdump__QModelIndex(d, value):
|
||||
def qdump__QDate(d, value):
|
||||
jd = int(value["jd"])
|
||||
if jd:
|
||||
d.putValue(jd, JulianDate)
|
||||
d.putValue(jd, "juliandate")
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
# FIXME: This improperly uses complex return values.
|
||||
@@ -218,7 +218,7 @@ def qdump__QDate(d, value):
|
||||
def qdump__QTime(d, value):
|
||||
mds = int(value["mds"])
|
||||
if mds >= 0:
|
||||
d.putValue(mds, MillisecondsSinceMidnight)
|
||||
d.putValue(mds, "millisecondssincemidnight")
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
# FIXME: This improperly uses complex return values.
|
||||
@@ -282,7 +282,7 @@ def qdump__QDateTime(d, value):
|
||||
idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr]
|
||||
elided, tz = d.encodeByteArrayHelper(d.extractPointer(idBase), limit=100)
|
||||
d.putValue("%s/%s/%s/%s/%s" % (msecs, spec, offset, tz, status),
|
||||
DateTimeInternal)
|
||||
"datetimeinternal")
|
||||
else:
|
||||
# This relies on the Qt4/Qt5 internal structure layout:
|
||||
# {sharedref(4), date(8), time(4+x)}
|
||||
@@ -302,7 +302,7 @@ def qdump__QDateTime(d, value):
|
||||
isValid = mds > 0
|
||||
if isValid:
|
||||
jd = d.extractInt(dateBase)
|
||||
d.putValue("%s/%s" % (jd, mds), JulianDateAndMillisecondsSinceMidnight)
|
||||
d.putValue("%s/%s" % (jd, mds), "juliandateandmillisecondssincemidnight")
|
||||
if isValid:
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
@@ -711,7 +711,7 @@ def qdump__QHostAddress(d, value):
|
||||
# value.d.d->ipString
|
||||
ipString = d.encodeString(ipStringAddress, limit=100)
|
||||
if d.extractByte(isParsedAddress) and len(ipString) > 0:
|
||||
d.putValue(ipString, Hex4EncodedLittleEndian)
|
||||
d.putValue(ipString, "utf16")
|
||||
else:
|
||||
# value.d.d->protocol:
|
||||
# QAbstractSocket::IPv4Protocol = 0
|
||||
@@ -723,7 +723,7 @@ def qdump__QHostAddress(d, value):
|
||||
address = ':'.join("%x" % int(data[i:i+4], 16) for i in xrange(0, 32, 4))
|
||||
scopeIdAddress = ipStringAddress + sizeofQString
|
||||
scopeId = d.encodeString(scopeIdAddress, limit=100)
|
||||
d.putValue("%s%%%s" % (address, scopeId), IPv6AddressAndHexScopeId)
|
||||
d.putValue("%s%%%s" % (address, scopeId), "ipv6addressandhexscopeid")
|
||||
elif proto == 0:
|
||||
# value.d.d->a
|
||||
a = d.extractInt(privAddress + 2 * sizeofQString)
|
||||
@@ -742,7 +742,7 @@ def qdump__QHostAddress(d, value):
|
||||
# value.d.d->ipString
|
||||
ipString = d.encodeString(ipStringAddress, limit=100)
|
||||
if d.extractByte(isParsedAddress) and len(ipString) > 0:
|
||||
d.putValue(ipString, Hex4EncodedLittleEndian)
|
||||
d.putValue(ipString, "utf16")
|
||||
else:
|
||||
# value.d.d->protocol:
|
||||
# QAbstractSocket::IPv4Protocol = 0
|
||||
@@ -756,7 +756,7 @@ def qdump__QHostAddress(d, value):
|
||||
address = ':'.join("%x" % int(data[i:i+4], 16) for i in xrange(0, 32, 4))
|
||||
scopeId = privAddress + sizeofQString + (0 if isQt5 else 24)
|
||||
scopeId = d.encodeString(scopeId, limit=100)
|
||||
d.putValue("%s%%%s" % (address, scopeId), IPv6AddressAndHexScopeId)
|
||||
d.putValue("%s%%%s" % (address, scopeId), "ipv6addressandhexscopeid")
|
||||
elif proto == 0:
|
||||
# value.d.d->a
|
||||
a = d.extractInt(privAddress + (2 * sizeofQString if isQt5 else 0))
|
||||
@@ -1131,16 +1131,16 @@ def qdump__QMetaObject(d, value):
|
||||
#d.putAddressItem("_data", data)
|
||||
#d.putAddressItem("_sd_", stringdata)
|
||||
#with SubItem(d, "_sd"):
|
||||
# d.putValue(d.readMemory(stringdata, size), Hex2EncodedLatin1)
|
||||
# d.putValue(d.readMemory(stringdata, size), "latin1")
|
||||
#with SubItem(d, "_cn"):
|
||||
# d.putValue(d.readMemory(stringdata + d.extractInt(data + 4), size), Hex2EncodedLatin1)
|
||||
# d.putValue(d.readMemory(stringdata + d.extractInt(data + 4), size), "latin1")
|
||||
|
||||
#for i in range(propertyCount):
|
||||
# with SubItem(d, "property_%s" % i):
|
||||
# x = data + (propertyData + 3 * i) * 4
|
||||
# literal = sd + d.extractInt(x) * byteArrayDataSize
|
||||
# ldata, lsize, lalloc = d.byteArrayDataHelper(literal)
|
||||
# d.putValue(d.readMemory(ldata, lsize), Hex2EncodedLatin1)
|
||||
# d.putValue(d.readMemory(ldata, lsize), "latin1")
|
||||
|
||||
# d.putNumChild(1)
|
||||
# if d.isExpanded():
|
||||
@@ -1304,7 +1304,7 @@ def _qdump__QObject(d, value):
|
||||
with SubItem(d, i):
|
||||
pp = p.cast(namesType.pointer()).dereference();
|
||||
d.putField("key", d.encodeByteArray(pp))
|
||||
d.putField("keyencoded", Hex2EncodedLatin1)
|
||||
d.putField("keyencoded", "latin1")
|
||||
qq = q.cast(valuesType.pointer().pointer())
|
||||
qq = qq.dereference();
|
||||
d.putField("address", d.cleanAddress(qq))
|
||||
@@ -1592,7 +1592,7 @@ def qdump__QRegExp(d, value):
|
||||
def qdump__QRegion(d, value):
|
||||
p = value["d"].dereference()["qt_rgn"]
|
||||
if d.isNull(p):
|
||||
d.putSpecialValue(SpecialEmptyValue)
|
||||
d.putSpecialValue("empty")
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
# struct QRegionPrivate:
|
||||
@@ -1806,7 +1806,7 @@ def qdump__QStringRef(d, value):
|
||||
data += 2 * int(value["m_position"])
|
||||
size = int(value["m_size"])
|
||||
s = d.readMemory(data, 2 * size)
|
||||
d.putValue(s, Hex4EncodedLittleEndian)
|
||||
d.putValue(s, "utf16")
|
||||
d.putPlainChildren(value)
|
||||
|
||||
|
||||
@@ -1873,7 +1873,7 @@ def qdump__QUrl(d, value):
|
||||
d.putValue("<invalid>")
|
||||
return
|
||||
encodedOriginalAddress = privAddress + 8 * d.ptrSize()
|
||||
d.putValue(d.encodeByteArrayHelper(d.extractPointer(encodedOriginalAddress), 100), Hex2EncodedLatin1)
|
||||
d.putValue(d.encodeByteArrayHelper(d.extractPointer(encodedOriginalAddress), 100), "latin1")
|
||||
d.putNumChild(8)
|
||||
if d.isExpanded():
|
||||
stringType = d.lookupType(d.qtNamespace() + "QString")
|
||||
@@ -1925,7 +1925,7 @@ def qdump__QUrl(d, value):
|
||||
url += "3a00"
|
||||
url += ''.join(["%02x00" % ord(c) for c in str(port)])
|
||||
url += path
|
||||
d.putValue(url, Hex4EncodedLittleEndian)
|
||||
d.putValue(url, "utf16")
|
||||
|
||||
displayFormat = d.currentItemFormat()
|
||||
if displayFormat == SeparateFormat:
|
||||
@@ -1937,13 +1937,13 @@ def qdump__QUrl(d, value):
|
||||
stringType = d.lookupType(d.qtNamespace() + "QString")
|
||||
with Children(d):
|
||||
d.putIntItem("port", port)
|
||||
d.putGenericItem("scheme", stringType, scheme, Hex4EncodedLittleEndian)
|
||||
d.putGenericItem("userName", stringType, userName, Hex4EncodedLittleEndian)
|
||||
d.putGenericItem("password", stringType, password, Hex4EncodedLittleEndian)
|
||||
d.putGenericItem("host", stringType, host, Hex4EncodedLittleEndian)
|
||||
d.putGenericItem("path", stringType, path, Hex4EncodedLittleEndian)
|
||||
d.putGenericItem("query", stringType, query, Hex4EncodedLittleEndian)
|
||||
d.putGenericItem("fragment", stringType, fragment, Hex4EncodedLittleEndian)
|
||||
d.putGenericItem("scheme", stringType, scheme, "utf16")
|
||||
d.putGenericItem("userName", stringType, userName, "utf16")
|
||||
d.putGenericItem("password", stringType, password, "utf16")
|
||||
d.putGenericItem("host", stringType, host, "utf16")
|
||||
d.putGenericItem("path", stringType, path, "utf16")
|
||||
d.putGenericItem("query", stringType, query, "utf16")
|
||||
d.putGenericItem("fragment", stringType, fragment, "utf16")
|
||||
d.putFields(value)
|
||||
|
||||
|
||||
@@ -2281,7 +2281,7 @@ def qdump__QXmlStreamStringRef(d, value):
|
||||
data += 2 * int(value["m_position"])
|
||||
size = int(value["m_size"])
|
||||
s = d.readMemory(data, 2 * size)
|
||||
d.putValue(s, Hex4EncodedLittleEndian)
|
||||
d.putValue(s, "utf16")
|
||||
d.putPlainChildren(value)
|
||||
|
||||
|
||||
@@ -2291,7 +2291,7 @@ def qdump__QXmlStreamAttribute(d, value):
|
||||
data += 2 * int(value["m_name"]["m_position"])
|
||||
size = int(value["m_name"]["m_size"])
|
||||
s = d.readMemory(data, 2 * size)
|
||||
d.putValue(s, Hex4EncodedLittleEndian)
|
||||
d.putValue(s, "utf16")
|
||||
d.putPlainChildren(value)
|
||||
|
||||
|
||||
@@ -2363,7 +2363,7 @@ def qdump__QV4__Value(d, value):
|
||||
d.putValue("%d" % vv)
|
||||
elif v & IsDoubleMask:
|
||||
d.putBetterType("%sQV4::Value (double)" % ns)
|
||||
d.putValue("%x" % (v ^ 0xffff800000000000), Hex2EncodedFloat8)
|
||||
d.putValue("%x" % (v ^ 0xffff800000000000), "float:8")
|
||||
elif d.isNull(v):
|
||||
d.putBetterType("%sQV4::Value (null)" % ns)
|
||||
d.putValue("(null)")
|
||||
@@ -2626,10 +2626,10 @@ def qdumpHelper__QJsonValue(d, data, base, pv):
|
||||
data = base + v;
|
||||
if latinOrIntValue:
|
||||
length = d.extractUShort(data)
|
||||
d.putValue(d.readMemory(data + 2, length), Hex2EncodedLatin1)
|
||||
d.putValue(d.readMemory(data + 2, length), "latin1")
|
||||
else:
|
||||
length = d.extractUInt(data)
|
||||
d.putValue(d.readMemory(data + 4, length * 2), Hex4EncodedLittleEndian)
|
||||
d.putValue(d.readMemory(data + 4, length * 2), "utf16")
|
||||
d.putNumChild(1)
|
||||
return
|
||||
if t == 4:
|
||||
@@ -2696,11 +2696,11 @@ def qdumpHelper__QJsonObject(d, data, obj):
|
||||
if isLatinKey:
|
||||
keyLength = d.extractUShort(keyStart)
|
||||
d.put('key="%s",' % d.readMemory(keyStart + 2, keyLength))
|
||||
d.put('keyencoded="%s",' % Hex2EncodedLatin1)
|
||||
d.put('keyencoded="latin1",')
|
||||
else:
|
||||
keyLength = d.extractUInt(keyStart)
|
||||
d.put('key="%s",' % d.readMemory(keyStart + 4, keyLength))
|
||||
d.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
|
||||
d.put('keyencoded="utf16",')
|
||||
|
||||
qdumpHelper__QJsonValue(d, data, obj, val)
|
||||
|
||||
|
||||
@@ -667,7 +667,7 @@ static std::string dumplocalHelper(ExtensionCommandContext &exc,PCSTR args, int
|
||||
return std::string();
|
||||
}
|
||||
std::wstring value;
|
||||
if (!dumpSimpleType(n->asSymbolGroupNode(), SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()), &value)) {
|
||||
if (!dumpSimpleType(n->asSymbolGroupNode(), SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()), &value, &std::string())) {
|
||||
*errorMessage = "Cannot dump " + iname;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ bool DumpParameters::recode(const std::string &type,
|
||||
const std::string &iname,
|
||||
const SymbolGroupValueContext &ctx,
|
||||
ULONG64 address,
|
||||
std::wstring *value, int *encoding) const
|
||||
std::wstring *value, std::string *encoding) const
|
||||
{
|
||||
const DumpParameterRecodeResult check
|
||||
= checkRecode(type, iname, *value, ctx, address, this);
|
||||
@@ -515,19 +515,19 @@ bool DumpParameters::recode(const std::string &type,
|
||||
switch (check.recommendedFormat) {
|
||||
case FormatLatin1String:
|
||||
*value = dataToHexW(check.buffer, check.buffer + check.size); // Latin1 + 0
|
||||
*encoding = DumpEncodingHex_Latin1_WithQuotes;
|
||||
*encoding = "latin1";
|
||||
break;
|
||||
case FormatUtf8String:
|
||||
*value = dataToHexW(check.buffer, check.buffer + check.size); // UTF8 + 0
|
||||
*encoding = DumpEncodingHex_Utf8_LittleEndian_WithQuotes;
|
||||
*encoding = "utf8";
|
||||
break;
|
||||
case FormatUtf16String: // Paranoia: make sure buffer is terminated at 2 byte borders
|
||||
*value = dataToHexW(check.buffer, check.buffer + check.size);
|
||||
*encoding = DumpEncodingHex_Utf16_LittleEndian_WithQuotes;
|
||||
*encoding = "utf16";
|
||||
break;
|
||||
case FormatUcs4String: // Paranoia: make sure buffer is terminated at 4 byte borders
|
||||
*value = dataToHexW(check.buffer, check.buffer + check.size); // UTF16 + 0
|
||||
*encoding = DumpEncodingHex_Ucs4_LittleEndian_WithQuotes;
|
||||
*encoding = "ucs4";
|
||||
break;
|
||||
}
|
||||
delete [] check.buffer;
|
||||
@@ -612,7 +612,6 @@ SymbolGroupNode::SymbolGroupNode(SymbolGroup *symbolGroup,
|
||||
, m_symbolGroup(symbolGroup)
|
||||
, m_module(module)
|
||||
, m_index(index)
|
||||
, m_dumperValueEncoding(0)
|
||||
, m_dumperType(-1)
|
||||
, m_dumperContainerSize(-1)
|
||||
, m_dumperSpecialInfo(0)
|
||||
@@ -920,18 +919,6 @@ static void fixValue(const std::string &type, std::wstring *value)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for ASCII-encode-able stuff. Plain characters + tabs at the most, no newline.
|
||||
static bool isSevenBitClean(const wchar_t *buf, size_t size)
|
||||
{
|
||||
const wchar_t *bufEnd = buf + size;
|
||||
for (const wchar_t *bufPtr = buf; bufPtr < bufEnd; bufPtr++) {
|
||||
const wchar_t c = *bufPtr;
|
||||
if (c > 127 || (c < 32 && c != 9))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string SymbolGroupNode::type() const
|
||||
{
|
||||
static char buf[BufSize];
|
||||
@@ -1059,7 +1046,7 @@ bool SymbolGroupNode::runSimpleDumpers(const SymbolGroupValueContext &ctx)
|
||||
return testFlags(SimpleDumperOk);
|
||||
}
|
||||
|
||||
std::wstring SymbolGroupNode::simpleDumpValue(const SymbolGroupValueContext &ctx, int *encoding)
|
||||
std::wstring SymbolGroupNode::simpleDumpValue(const SymbolGroupValueContext &ctx, std::string *encoding)
|
||||
{
|
||||
if (testFlags(Uninitialized))
|
||||
return L"<not in scope>";
|
||||
@@ -1114,7 +1101,7 @@ int SymbolGroupNode::dumpNode(std::ostream &str,
|
||||
const std::string watchExp = t.empty() ? aName : watchExpression(addr, t, m_dumperType, m_module);
|
||||
SymbolGroupNode::dumpBasicData(str, aName, aFullIName, t, watchExp);
|
||||
|
||||
int encoding = 0;
|
||||
std::string encoding;
|
||||
std::wstring value = simpleDumpValue(ctx, &encoding);
|
||||
|
||||
if (addr) {
|
||||
@@ -1138,20 +1125,15 @@ int SymbolGroupNode::dumpNode(std::ostream &str,
|
||||
bool valueEditable = !uninitialized;
|
||||
bool valueEnabled = !uninitialized;
|
||||
|
||||
if (encoding) {
|
||||
if (encoding.size()) {
|
||||
str << ",valueencoded=\"" << encoding << "\",value=\"" << gdbmiWStringFormat(value) <<'"';
|
||||
} else if (dumpParameters.recode(t, aFullIName, ctx, addr, &value, &encoding)) {
|
||||
str << ",valueencoded=\"" << encoding
|
||||
<< "\",value=\"" << gdbmiWStringFormat(value) <<'"';
|
||||
} else { // As is: ASCII or hex encoded?
|
||||
if (isSevenBitClean(value.c_str(), value.size())) {
|
||||
str << ",valueencoded=\"" << DumpEncodingAscii << "\",value=\""
|
||||
<< gdbmiWStringFormat(value) << '"';
|
||||
} else {
|
||||
str << ",valueencoded=\"" << DumpEncodingHex_Utf16_LittleEndian << "\",value=\"";
|
||||
hexEncode(str, reinterpret_cast<const unsigned char*>(value.c_str()), value.size() * 2);
|
||||
str << ",valueencoded=\"utf16:2:0\",value=\"";
|
||||
hexEncode(str, reinterpret_cast<const unsigned char *>(value.c_str()), value.size() * sizeof(wchar_t));
|
||||
str << '"';
|
||||
}
|
||||
const int format = dumpParameters.format(t, aFullIName);
|
||||
if (format > 0)
|
||||
dumpEditValue(this, ctx, format, str);
|
||||
|
||||
@@ -48,23 +48,6 @@ struct SymbolGroupValueContext;
|
||||
class SymbolGroupNode;
|
||||
class MemoryHandle;
|
||||
|
||||
enum DumpEncoding // WatchData encoding of GDBMI values
|
||||
{
|
||||
DumpEncodingAscii = 0,
|
||||
DumpEncodingBase64_Utf16_WithQuotes = 2,
|
||||
DumpEncodingHex_Ucs4_LittleEndian_WithQuotes = 3,
|
||||
DumpEncodingBase64_Utf16 = 4,
|
||||
DumpEncodingHex_Latin1_WithQuotes = 6,
|
||||
DumpEncodingHex_Utf16_LittleEndian_WithQuotes = 7,
|
||||
DumpEncodingHex_Utf8_LittleEndian_WithQuotes = 9,
|
||||
DumpEncodingHex_Utf16_LittleEndian = 12,
|
||||
DumpEncodingJulianDate = 14,
|
||||
DumpEncodingMillisecondsSinceMidnight = 15,
|
||||
DumpEncodingJulianDateAndMillisecondsSinceMidnight = 16,
|
||||
DumpEncodingIPv6AddressAndHexScopeId = 27,
|
||||
DumpEncodingMillisecondsSinceEpoch = 29
|
||||
};
|
||||
|
||||
// Helper struct used for check results when recoding CDB char pointer output.
|
||||
struct DumpParameterRecodeResult
|
||||
{
|
||||
@@ -102,7 +85,7 @@ struct DumpParameters
|
||||
bool recode(const std::string &type, const std::string &iname,
|
||||
const SymbolGroupValueContext &ctx,
|
||||
ULONG64 address,
|
||||
std::wstring *value, int *encoding) const;
|
||||
std::wstring *value, std::string *encoding) const;
|
||||
int format(const std::string &type, const std::string &iname) const;
|
||||
|
||||
unsigned dumpFlags;
|
||||
@@ -269,7 +252,7 @@ public:
|
||||
std::wstring symbolGroupFixedValue() const;
|
||||
|
||||
bool assign(const std::string &value, std::string *errorMessage = 0);
|
||||
std::wstring simpleDumpValue(const SymbolGroupValueContext &ctx, int *encoding);
|
||||
std::wstring simpleDumpValue(const SymbolGroupValueContext &ctx, std::string *encoding);
|
||||
|
||||
// A quick check if symbol is valid by checking for inaccessible value
|
||||
bool isMemoryAccessible() const;
|
||||
@@ -319,7 +302,7 @@ private:
|
||||
ULONG m_index;
|
||||
DEBUG_SYMBOL_PARAMETERS m_parameters; // Careful when using ParentSymbol. It might not be correct.
|
||||
std::wstring m_dumperValue;
|
||||
int m_dumperValueEncoding;
|
||||
std::string m_dumperValueEncoding;
|
||||
int m_dumperType;
|
||||
int m_dumperContainerSize;
|
||||
void *m_dumperSpecialInfo; // Opaque information passed from simple to complex dumpers
|
||||
|
||||
@@ -1710,7 +1710,7 @@ static unsigned qAtomicIntSize(const SymbolGroupValueContext &ctx)
|
||||
}
|
||||
|
||||
// Dump a QByteArray
|
||||
static inline bool dumpQByteArray(const SymbolGroupValue &v, std::wostream &str, int *encoding,
|
||||
static inline bool dumpQByteArray(const SymbolGroupValue &v, std::wostream &str, std::string *encoding,
|
||||
MemoryHandle **memoryHandle = 0)
|
||||
{
|
||||
const QtInfo &qtInfo = QtInfo::get(v.context());
|
||||
@@ -1735,7 +1735,7 @@ static inline bool dumpQByteArray(const SymbolGroupValue &v, std::wostream &str,
|
||||
|
||||
// Qt 5: Data start at offset past the 'd' of type QByteArrayData.
|
||||
if (encoding)
|
||||
*encoding = DumpEncodingHex_Latin1_WithQuotes;
|
||||
*encoding = "latin1";
|
||||
wchar_t oldFill = str.fill(wchar_t('0'));
|
||||
str << std::hex;
|
||||
char *memory;
|
||||
@@ -1839,7 +1839,7 @@ static bool dumpQByteArrayFromQPrivateClass(const SymbolGroupValue &v,
|
||||
QPrivateDumpMode mode,
|
||||
unsigned additionalOffset,
|
||||
std::wostream &str,
|
||||
int *encoding)
|
||||
std::string *encoding)
|
||||
{
|
||||
std::string errorMessage;
|
||||
const ULONG64 byteArrayAddress = addressOfQPrivateMember(v, mode, additionalOffset);
|
||||
@@ -1935,7 +1935,7 @@ static inline bool dumpQFile(const SymbolGroupValue &v, std::wostream &str)
|
||||
return dumpQStringFromQPrivateClass(v, QPDM_qVirtual, qFileBasePrivateSize, str);
|
||||
}
|
||||
|
||||
static inline bool dumpQIPv6Address(const SymbolGroupValue &v, std::wostream &str, int *encoding)
|
||||
static inline bool dumpQIPv6Address(const SymbolGroupValue &v, std::wostream &str, std::string *encoding)
|
||||
{
|
||||
unsigned char *p = SymbolGroupValue::readMemory( v.context().dataspaces, v["c"].address(), 16);
|
||||
if (!p || !encoding)
|
||||
@@ -1950,12 +1950,12 @@ static inline bool dumpQIPv6Address(const SymbolGroupValue &v, std::wostream &st
|
||||
}
|
||||
str << std::dec;
|
||||
str.fill(oldFill);
|
||||
*encoding = DumpEncodingIPv6AddressAndHexScopeId;
|
||||
*encoding = "ipv6addressandhexscopeid";
|
||||
return true;
|
||||
}
|
||||
/* Dump QHostAddress, for whose private class no debugging information is available.
|
||||
* Dump string 'ipString' past of its private class. Does not currently work? */
|
||||
static inline bool dumpQHostAddress(const SymbolGroupValue &v, std::wostream &str, int *encoding)
|
||||
static inline bool dumpQHostAddress(const SymbolGroupValue &v, std::wostream &str, std::string *encoding)
|
||||
{
|
||||
// Determine offset in private struct: qIPv6AddressType (array, unaligned) + uint32 + enum.
|
||||
const QtInfo info = QtInfo::get(v.context());
|
||||
@@ -2181,13 +2181,13 @@ static inline bool dumpQFlags(const SymbolGroupValue &v, std::wostream &str)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool dumpQDate(const SymbolGroupValue &v, std::wostream &str, int *encoding)
|
||||
static bool dumpQDate(const SymbolGroupValue &v, std::wostream &str, std::string *encoding)
|
||||
{
|
||||
if (const SymbolGroupValue julianDayV = v["jd"]) {
|
||||
if (julianDayV.intValue() > 0) {
|
||||
str << julianDayV.intValue();
|
||||
if (encoding)
|
||||
*encoding = DumpEncodingJulianDate;
|
||||
*encoding = "juliandate";
|
||||
} else {
|
||||
str << L"(invalid)";
|
||||
}
|
||||
@@ -2196,19 +2196,19 @@ static bool dumpQDate(const SymbolGroupValue &v, std::wostream &str, int *encodi
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool dumpQTime(const SymbolGroupValue &v, std::wostream &str, int *encoding)
|
||||
static bool dumpQTime(const SymbolGroupValue &v, std::wostream &str, std::string *encoding)
|
||||
{
|
||||
if (const SymbolGroupValue milliSecsV = v["mds"]) {
|
||||
const int milliSecs = milliSecsV.intValue();
|
||||
str << milliSecs;
|
||||
if (encoding)
|
||||
*encoding = DumpEncodingMillisecondsSinceMidnight;
|
||||
*encoding = "millisecondssincemidnight";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool dumpQTimeZone(const SymbolGroupValue &v, std::wostream &str, int *encoding)
|
||||
static bool dumpQTimeZone(const SymbolGroupValue &v, std::wostream &str, std::string *encoding)
|
||||
{
|
||||
if (!dumpQByteArrayFromQPrivateClass(v, QPDM_qSharedDataPadded, SymbolGroupValue::pointerSize(), str, encoding))
|
||||
str << L"(null)";
|
||||
@@ -2220,7 +2220,7 @@ static bool dumpQTimeZoneFromQPrivateClass(const SymbolGroupValue &v,
|
||||
QPrivateDumpMode mode,
|
||||
unsigned additionalOffset,
|
||||
std::wostream &str,
|
||||
int *encoding)
|
||||
std::string *encoding)
|
||||
{
|
||||
std::string errorMessage;
|
||||
const ULONG64 timeZoneAddress = addressOfQPrivateMember(v, mode, additionalOffset);
|
||||
@@ -2250,7 +2250,7 @@ static bool dumpQTimeZoneFromQPrivateClass(const SymbolGroupValue &v,
|
||||
|
||||
// QDateTime has an unexported private class. Obtain date and time
|
||||
// from memory.
|
||||
static bool dumpQDateTime(const SymbolGroupValue &v, std::wostream &str, int *encoding)
|
||||
static bool dumpQDateTime(const SymbolGroupValue &v, std::wostream &str, std::string *encoding)
|
||||
{
|
||||
// QDate is 64bit starting from Qt 5 which is always aligned 64bit.
|
||||
if (QtInfo::get(v.context()).version == 5) {
|
||||
@@ -2298,7 +2298,7 @@ static bool dumpQDateTime(const SymbolGroupValue &v, std::wostream &str, int *en
|
||||
<< status;
|
||||
|
||||
if (encoding)
|
||||
*encoding = DumpEncodingMillisecondsSinceEpoch;
|
||||
*encoding = "datetimeinternal";
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2319,7 +2319,7 @@ static bool dumpQDateTime(const SymbolGroupValue &v, std::wostream &str, int *en
|
||||
timeAddr, SymbolGroupValue::intSize(), 0);
|
||||
str << date << '/' << time;
|
||||
if (encoding)
|
||||
*encoding = DumpEncodingJulianDateAndMillisecondsSinceMidnight;
|
||||
*encoding = "juliandateandmillisecondssincemidnight";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2651,7 +2651,7 @@ static inline std::string
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool dumpQVariant(const SymbolGroupValue &v, std::wostream &str, int *encoding,
|
||||
static bool dumpQVariant(const SymbolGroupValue &v, std::wostream &str, std::string *encoding,
|
||||
void **specialInfoIn = 0)
|
||||
{
|
||||
const QtInfo &qtInfo = QtInfo::get(v.context());
|
||||
@@ -2695,7 +2695,8 @@ static bool dumpQVariant(const SymbolGroupValue &v, std::wostream &str, int *enc
|
||||
if (const SymbolGroupValue mv = dataV.typeCast(vmType.c_str())) {
|
||||
SymbolGroupNode *mapNode = mv.node();
|
||||
std::wstring value;
|
||||
if (dumpSimpleType(mapNode, dataV.context(), &value) == SymbolGroupNode::SimpleDumperOk) {
|
||||
if (dumpSimpleType(mapNode, dataV.context(), &value, &std::string())
|
||||
== SymbolGroupNode::SimpleDumperOk) {
|
||||
str << value;
|
||||
if (specialInfoIn)
|
||||
*specialInfoIn = mapNode;
|
||||
@@ -2709,7 +2710,8 @@ static bool dumpQVariant(const SymbolGroupValue &v, std::wostream &str, int *enc
|
||||
if (const SymbolGroupValue vl = dataV.typeCast(vLType.c_str())) {
|
||||
SymbolGroupNode *vListNode = vl.node();
|
||||
std::wstring value;
|
||||
if (dumpSimpleType(vListNode, dataV.context(), &value) == SymbolGroupNode::SimpleDumperOk) {
|
||||
if (dumpSimpleType(vListNode, dataV.context(), &value, &std::string())
|
||||
== SymbolGroupNode::SimpleDumperOk) {
|
||||
str << value;
|
||||
if (specialInfoIn)
|
||||
*specialInfoIn = vListNode;
|
||||
@@ -2734,7 +2736,8 @@ static bool dumpQVariant(const SymbolGroupValue &v, std::wostream &str, int *enc
|
||||
if (const SymbolGroupValue sl = dataV.typeCast(qtInfo.prependQtCoreModule("QStringList *").c_str())) {
|
||||
SymbolGroupNode *listNode = sl.node();
|
||||
std::wstring value;
|
||||
if (dumpSimpleType(listNode, dataV.context(), &value) == SymbolGroupNode::SimpleDumperOk) {
|
||||
if (dumpSimpleType(listNode, dataV.context(), &value, &std::string())
|
||||
== SymbolGroupNode::SimpleDumperOk) {
|
||||
str << value;
|
||||
if (specialInfoIn)
|
||||
*specialInfoIn = listNode;
|
||||
@@ -2821,7 +2824,7 @@ static bool dumpQVariant(const SymbolGroupValue &v, std::wostream &str, int *enc
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool dumpQSharedPointer(const SymbolGroupValue &v, std::wostream &str, int *encoding, void **specialInfoIn = 0)
|
||||
static inline bool dumpQSharedPointer(const SymbolGroupValue &v, std::wostream &str, std::string *encoding, void **specialInfoIn = 0)
|
||||
{
|
||||
const SymbolGroupValue externalRefCountV = v[unsigned(0)];
|
||||
const QtInfo qtInfo = QtInfo::get(v.context());
|
||||
@@ -2865,7 +2868,7 @@ static inline bool dumpQSharedPointer(const SymbolGroupValue &v, std::wostream &
|
||||
|
||||
// Dump builtin simple types using SymbolGroupValue expressions.
|
||||
unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
|
||||
std::wstring *s, int *encoding /* = 0 */, int *knownTypeIn /* = 0 */,
|
||||
std::wstring *s, std::string *encoding, int *knownTypeIn /* = 0 */,
|
||||
int *containerSizeIn /* = 0 */,
|
||||
void **specialInfoIn /* = 0 */,
|
||||
MemoryHandle **memoryHandleIn /* = 0 */)
|
||||
|
||||
@@ -255,7 +255,7 @@ void formatKnownTypeFlags(std::ostream &os, KnownType kt);
|
||||
// complex dumpers
|
||||
unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
|
||||
std::wstring *s,
|
||||
int *encoding = 0,
|
||||
std::string *encoding,
|
||||
int *knownType = 0,
|
||||
int *containerSizeIn = 0,
|
||||
void **specialInfoIn = 0,
|
||||
|
||||
@@ -560,139 +560,101 @@ static void getDateTime(qint64 msecs, int status, QDate *date, QTime *time)
|
||||
*time = (status & NullTime) ? QTime() : QTime::fromMSecsSinceStartOfDay(ds);
|
||||
}
|
||||
|
||||
QString decodeData(const QByteArray &ba, DebuggerEncoding encoding)
|
||||
QString decodeData(const QByteArray &ba, const QByteArray &encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
case Unencoded8Bit: // 0
|
||||
return quoteUnprintableLatin1(ba);
|
||||
case Base64Encoded8BitWithQuotes: { // 1, used for QByteArray
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
QString rc = doubleQuote;
|
||||
rc += quoteUnprintableLatin1(QByteArray::fromBase64(ba));
|
||||
rc += doubleQuote;
|
||||
return rc;
|
||||
if (encoding.isEmpty())
|
||||
return quoteUnprintableLatin1(ba); // The common case.
|
||||
|
||||
if (encoding == "empty")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<empty>");
|
||||
if (encoding == "minimumitemcount")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<at least %n items>", 0, ba.toInt());
|
||||
if (encoding == "undefined")
|
||||
return QLatin1String("Undefined");
|
||||
if (encoding == "null")
|
||||
return QLatin1String("Null");
|
||||
if (encoding == "itemcount")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<%n items>", 0, ba.toInt());
|
||||
if (encoding == "notaccessible")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not accessible>");
|
||||
if (encoding == "optimizedout")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<optimized out>");
|
||||
if (encoding == "nullreference")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<null reference>");
|
||||
if (encoding == "emptystructure")
|
||||
return QLatin1String("{...}");
|
||||
if (encoding == "uninitialized")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<uninitialized>");
|
||||
if (encoding == "invalid")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<invalid>");
|
||||
if (encoding == "notcallable")
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not callable>");
|
||||
|
||||
DebuggerEncoding enc(encoding);
|
||||
QString result;
|
||||
switch (enc.type) {
|
||||
case DebuggerEncoding::Unencoded: {
|
||||
result = quoteUnprintableLatin1(ba);
|
||||
break;
|
||||
}
|
||||
case Base64Encoded16BitWithQuotes: { // 2, used for QString
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
const QByteArray decodedBa = QByteArray::fromBase64(ba);
|
||||
QString rc = doubleQuote;
|
||||
rc += QString::fromUtf16(reinterpret_cast<const ushort *>
|
||||
case DebuggerEncoding::HexEncodedLocal8Bit: {
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
result = QString::fromLocal8Bit(decodedBa.data(), decodedBa.size());
|
||||
break;
|
||||
}
|
||||
case DebuggerEncoding::HexEncodedLatin1: {
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
result = QString::fromLatin1(decodedBa.data(), decodedBa.size());
|
||||
break;
|
||||
}
|
||||
case DebuggerEncoding::HexEncodedUtf8: {
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
result = QString::fromUtf8(decodedBa.data(), decodedBa.size());
|
||||
break;
|
||||
}
|
||||
case DebuggerEncoding::HexEncodedUtf16: {
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
result = QString::fromUtf16(reinterpret_cast<const ushort *>
|
||||
(decodedBa.data()), decodedBa.size() / 2);
|
||||
rc += doubleQuote;
|
||||
return rc;
|
||||
break;
|
||||
}
|
||||
case Base64Encoded32BitWithQuotes: { // 3
|
||||
const QByteArray decodedBa = QByteArray::fromBase64(ba);
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
QString rc = doubleQuote;
|
||||
rc += QString::fromUcs4(reinterpret_cast<const uint *>
|
||||
case DebuggerEncoding::HexEncodedUcs4: {
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
result = QString::fromUcs4(reinterpret_cast<const uint *>
|
||||
(decodedBa.data()), decodedBa.size() / 4);
|
||||
rc += doubleQuote;
|
||||
return rc;
|
||||
break;
|
||||
}
|
||||
case Base64Encoded16Bit: { // 4, without quotes (see 2)
|
||||
const QByteArray decodedBa = QByteArray::fromBase64(ba);
|
||||
return QString::fromUtf16(reinterpret_cast<const ushort *>
|
||||
(decodedBa.data()), decodedBa.size() / 2);
|
||||
}
|
||||
case Base64Encoded8Bit: { // 5, without quotes (see 1)
|
||||
return quoteUnprintableLatin1(QByteArray::fromBase64(ba));
|
||||
}
|
||||
case Hex2EncodedLatin1WithQuotes: { // 6, %02x encoded 8 bit Latin1 data
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return doubleQuote + QString::fromLatin1(decodedBa, decodedBa.size()) + doubleQuote;
|
||||
}
|
||||
case Hex4EncodedLittleEndianWithQuotes: { // 7, %04x encoded 16 bit data
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return doubleQuote + QString::fromUtf16(reinterpret_cast<const ushort *>
|
||||
(decodedBa.data()), decodedBa.size() / 2) + doubleQuote;
|
||||
}
|
||||
case Hex8EncodedLittleEndianWithQuotes: { // 8, %08x encoded 32 bit data
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return doubleQuote + QString::fromUcs4(reinterpret_cast<const uint *>
|
||||
(decodedBa.data()), decodedBa.size() / 4) + doubleQuote;
|
||||
}
|
||||
case Hex2EncodedUtf8WithQuotes: { // 9, %02x encoded 8 bit UTF-8 data
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return doubleQuote + QString::fromUtf8(decodedBa) + doubleQuote;
|
||||
}
|
||||
case Hex8EncodedBigEndian: { // 10, %08x encoded 32 bit data
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
for (int i = 0; i < decodedBa.size() - 3; i += 4) {
|
||||
char c = decodedBa.at(i);
|
||||
decodedBa[i] = decodedBa.at(i + 3);
|
||||
decodedBa[i + 3] = c;
|
||||
c = decodedBa.at(i + 1);
|
||||
decodedBa[i + 1] = decodedBa.at(i + 2);
|
||||
decodedBa[i + 2] = c;
|
||||
}
|
||||
return doubleQuote + QString::fromUcs4(reinterpret_cast<const uint *>
|
||||
(decodedBa.data()), decodedBa.size() / 4) + doubleQuote;
|
||||
}
|
||||
case Hex4EncodedBigEndianWithQuotes: { // 11, %04x encoded 16 bit data
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
for (int i = 0; i < decodedBa.size(); i += 2) {
|
||||
char c = decodedBa.at(i);
|
||||
decodedBa[i] = decodedBa.at(i + 1);
|
||||
decodedBa[i + 1] = c;
|
||||
}
|
||||
return doubleQuote + QString::fromUtf16(reinterpret_cast<const ushort *>
|
||||
(decodedBa.data()), decodedBa.size() / 2) + doubleQuote;
|
||||
}
|
||||
case Hex4EncodedLittleEndianWithoutQuotes: { // 12, see 7, without quotes
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return QString::fromUtf16(reinterpret_cast<const ushort *>
|
||||
(decodedBa.data()), decodedBa.size() / 2);
|
||||
}
|
||||
case Hex2EncodedLocal8BitWithQuotes: { // 13, %02x encoded 8 bit UTF-8 data
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return doubleQuote + QString::fromLocal8Bit(decodedBa) + doubleQuote;
|
||||
}
|
||||
case JulianDate: { // 14, an integer count
|
||||
case DebuggerEncoding::JulianDate: {
|
||||
const QDate date = dateFromData(ba.toInt());
|
||||
return date.isValid() ? date.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
||||
}
|
||||
case MillisecondsSinceMidnight: { // 15
|
||||
case DebuggerEncoding::MillisecondsSinceMidnight: {
|
||||
const QTime time = timeFromData(ba.toInt());
|
||||
return time.isValid() ? time.toString(Qt::TextDate) : QLatin1String("(invalid)");
|
||||
}
|
||||
case JulianDateAndMillisecondsSinceMidnight: { // 16
|
||||
case DebuggerEncoding::JulianDateAndMillisecondsSinceMidnight: {
|
||||
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
|
||||
case DebuggerEncoding::HexEncodedUnsignedInteger:
|
||||
case DebuggerEncoding::HexEncodedSignedInteger:
|
||||
qDebug("not implemented"); // Only used in Arrays, see watchdata.cpp
|
||||
return QString();
|
||||
case Hex2EncodedFloat4: { // 25
|
||||
case DebuggerEncoding::HexEncodedFloat: {
|
||||
const QByteArray s = QByteArray::fromHex(ba);
|
||||
QTC_ASSERT(s.size() == 4, break);
|
||||
if (enc.size == 4) {
|
||||
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);
|
||||
if (enc.size == 8) {
|
||||
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
|
||||
}
|
||||
case DebuggerEncoding::IPv6AddressAndHexScopeId: { // 16 hex-encoded bytes, "%" and the string-encoded scope
|
||||
const int p = ba.indexOf('%');
|
||||
QHostAddress ip6(QString::fromLatin1(p == -1 ? ba : ba.left(p)));
|
||||
if (ip6.isNull())
|
||||
@@ -704,11 +666,7 @@ QString decodeData(const QByteArray &ba, DebuggerEncoding encoding)
|
||||
scopeId.length() / 2));
|
||||
return ip6.toString();
|
||||
}
|
||||
case Hex2EncodedUtf8WithoutQuotes: { // 28, %02x encoded 8 bit UTF-8 data without quotes
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return QString::fromUtf8(decodedBa);
|
||||
}
|
||||
case DateTimeInternal: { // 29, DateTimeInternal: msecs, spec, offset, tz, status
|
||||
case DebuggerEncoding::DateTimeInternal: { // DateTimeInternal: msecs, spec, offset, tz, status
|
||||
int p0 = ba.indexOf('/');
|
||||
int p1 = ba.indexOf('/', p0 + 1);
|
||||
int p2 = ba.indexOf('/', p1 + 1);
|
||||
@@ -740,47 +698,17 @@ QString decodeData(const QByteArray &ba, DebuggerEncoding encoding)
|
||||
}
|
||||
return dateTime.toString();
|
||||
}
|
||||
case SpecialEmptyValue: { // 30
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<empty>");
|
||||
}
|
||||
case SpecialUninitializedValue: { // 31
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<uninitialized>");
|
||||
}
|
||||
case SpecialInvalidValue: { // 32
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<invalid>");
|
||||
}
|
||||
case SpecialNotAccessibleValue: { // 33
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not accessible>");
|
||||
}
|
||||
case SpecialItemCountValue: { // 34
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<%n items>", 0, ba.toInt());
|
||||
}
|
||||
case SpecialMinimumItemCountValue: { // 35
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<at least %n items>", 0, ba.toInt());
|
||||
}
|
||||
case SpecialNotCallableValue: { // 36
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<not callable>");
|
||||
}
|
||||
case SpecialNullReferenceValue: { // 37
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<null reference>");
|
||||
}
|
||||
case SpecialOptimizedOutValue: { // 38
|
||||
return QCoreApplication::translate("Debugger::Internal::WatchHandler", "<optimized out>");
|
||||
}
|
||||
case SpecialEmptyStructureValue: { // 39
|
||||
return QLatin1String("{...}");
|
||||
}
|
||||
case SpecialUndefinedValue: { // 40
|
||||
return QLatin1String("Undefined");
|
||||
}
|
||||
case SpecialNullValue: { // 41
|
||||
return QLatin1String("Null");
|
||||
}
|
||||
}
|
||||
qDebug() << "ENCODING ERROR: " << encoding;
|
||||
qDebug() << "ENCODING ERROR: " << enc.type;
|
||||
return QCoreApplication::translate("Debugger", "<Encoding error>");
|
||||
}
|
||||
|
||||
if (enc.quotes) {
|
||||
const QChar doubleQuote(QLatin1Char('"'));
|
||||
result = doubleQuote + result + doubleQuote;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DebuggerCommand
|
||||
@@ -897,23 +825,61 @@ QByteArray DebuggerCommand::argsToString() const
|
||||
return args.toString().toLatin1();
|
||||
}
|
||||
|
||||
DebuggerEncoding debuggerEncoding(const QByteArray &data)
|
||||
DebuggerEncoding::DebuggerEncoding(const QByteArray &data)
|
||||
{
|
||||
if (data == "utf16")
|
||||
return Hex4EncodedLittleEndianWithQuotes;
|
||||
if (data == "empty")
|
||||
return SpecialEmptyValue;
|
||||
if (data == "minimumitemcount")
|
||||
return SpecialMinimumItemCountValue;
|
||||
if (data == "undefined")
|
||||
return SpecialUndefinedValue;
|
||||
if (data == "null")
|
||||
return SpecialNullValue;
|
||||
if (data == "itemcount")
|
||||
return SpecialItemCountValue;
|
||||
if (data == "notaccessible")
|
||||
return SpecialNotAccessibleValue;
|
||||
return DebuggerEncoding(data.toInt());
|
||||
const QByteArrayList l = data.split(':');
|
||||
|
||||
const QByteArray &t = l.at(0);
|
||||
if (t == "latin1") {
|
||||
type = HexEncodedLatin1;
|
||||
size = 1;
|
||||
quotes = true;
|
||||
} else if (t == "local8bit") {
|
||||
type = HexEncodedLocal8Bit;
|
||||
size = 1;
|
||||
quotes = true;
|
||||
} else if (t == "utf8") {
|
||||
type = HexEncodedUtf8;
|
||||
size = 1;
|
||||
quotes = true;
|
||||
} else if (t == "utf16") {
|
||||
type = HexEncodedUtf16;
|
||||
size = 2;
|
||||
quotes = true;
|
||||
} else if (t == "ucs4") {
|
||||
type = HexEncodedUcs4;
|
||||
size = 4;
|
||||
quotes = true;
|
||||
} else if (t == "int") {
|
||||
type = HexEncodedSignedInteger;
|
||||
} else if (t == "uint") {
|
||||
type = HexEncodedUnsignedInteger;
|
||||
} else if (t == "float") {
|
||||
type = HexEncodedFloat;
|
||||
} else if (t == "juliandate") {
|
||||
type = JulianDate;
|
||||
} else if (t == "juliandateandmillisecondssincemidnight") {
|
||||
type = JulianDateAndMillisecondsSinceMidnight;
|
||||
} else if (t == "millisecondssincemidnight") {
|
||||
type = MillisecondsSinceMidnight;
|
||||
} else if (t == "ipv6addressandhexscopeid") {
|
||||
type = IPv6AddressAndHexScopeId;
|
||||
} else if (t == "datetimeinternal") {
|
||||
type = DateTimeInternal;
|
||||
} else if (!t.isEmpty()) {
|
||||
qDebug() << "CANNOT DECODE ENCODING" << data;
|
||||
}
|
||||
|
||||
if (l.size() >= 2)
|
||||
size = l.at(1).toInt();
|
||||
|
||||
if (l.size() >= 3)
|
||||
quotes = bool(l.at(2).toInt());
|
||||
}
|
||||
|
||||
QString DebuggerEncoding::toString() const
|
||||
{
|
||||
return QString::fromLatin1("%1:%2:%3").arg(type).arg(size).arg(quotes);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -158,62 +158,37 @@ 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
|
||||
class DebuggerEncoding
|
||||
{
|
||||
Unencoded8Bit = 0,
|
||||
Base64Encoded8BitWithQuotes = 1,
|
||||
Base64Encoded16BitWithQuotes = 2,
|
||||
Base64Encoded32BitWithQuotes = 3,
|
||||
Base64Encoded16Bit = 4,
|
||||
Base64Encoded8Bit = 5,
|
||||
Hex2EncodedLatin1WithQuotes = 6,
|
||||
Hex4EncodedLittleEndianWithQuotes = 7,
|
||||
Hex8EncodedLittleEndianWithQuotes = 8,
|
||||
Hex2EncodedUtf8WithQuotes = 9,
|
||||
Hex8EncodedBigEndian = 10,
|
||||
Hex4EncodedBigEndianWithQuotes = 11,
|
||||
Hex4EncodedLittleEndianWithoutQuotes = 12,
|
||||
Hex2EncodedLocal8BitWithQuotes = 13,
|
||||
JulianDate = 14,
|
||||
MillisecondsSinceMidnight = 15,
|
||||
JulianDateAndMillisecondsSinceMidnight = 16,
|
||||
Hex2EncodedInt1 = 17,
|
||||
Hex2EncodedInt2 = 18,
|
||||
Hex2EncodedInt4 = 19,
|
||||
Hex2EncodedInt8 = 20,
|
||||
Hex2EncodedUInt1 = 21,
|
||||
Hex2EncodedUInt2 = 22,
|
||||
Hex2EncodedUInt4 = 23,
|
||||
Hex2EncodedUInt8 = 24,
|
||||
Hex2EncodedFloat4 = 25,
|
||||
Hex2EncodedFloat8 = 26,
|
||||
IPv6AddressAndHexScopeId = 27,
|
||||
Hex2EncodedUtf8WithoutQuotes = 28,
|
||||
DateTimeInternal = 29,
|
||||
SpecialEmptyValue = 30,
|
||||
SpecialUninitializedValue = 31,
|
||||
SpecialInvalidValue = 32,
|
||||
SpecialNotAccessibleValue = 33,
|
||||
SpecialItemCountValue = 34,
|
||||
SpecialMinimumItemCountValue = 35,
|
||||
SpecialNotCallableValue = 36,
|
||||
SpecialNullReferenceValue = 37,
|
||||
SpecialOptimizedOutValue = 38,
|
||||
SpecialEmptyStructureValue = 39,
|
||||
SpecialUndefinedValue = 40,
|
||||
SpecialNullValue = 41
|
||||
public:
|
||||
enum EncodingType {
|
||||
Unencoded,
|
||||
HexEncodedLocal8Bit,
|
||||
HexEncodedLatin1,
|
||||
HexEncodedUtf8,
|
||||
HexEncodedUtf16,
|
||||
HexEncodedUcs4,
|
||||
HexEncodedSignedInteger,
|
||||
HexEncodedUnsignedInteger,
|
||||
HexEncodedFloat,
|
||||
JulianDate,
|
||||
MillisecondsSinceMidnight,
|
||||
JulianDateAndMillisecondsSinceMidnight,
|
||||
IPv6AddressAndHexScopeId,
|
||||
DateTimeInternal,
|
||||
};
|
||||
|
||||
DebuggerEncoding debuggerEncoding(const QByteArray &data);
|
||||
DebuggerEncoding() {}
|
||||
explicit DebuggerEncoding(const QByteArray &data);
|
||||
QString toString() const;
|
||||
|
||||
EncodingType type = Unencoded;
|
||||
int size = 0;
|
||||
bool quotes = false;
|
||||
};
|
||||
|
||||
// Decode string data as returned by the dumper helpers.
|
||||
QString decodeData(const QByteArray &baIn, DebuggerEncoding encoding);
|
||||
QString decodeData(const QByteArray &baIn, const QByteArray &encoding);
|
||||
|
||||
|
||||
// These enum values correspond to possible value display format requests,
|
||||
|
||||
@@ -3387,8 +3387,7 @@ void GdbEngine::handleThreadNames(const DebuggerResponse &response)
|
||||
foreach (const GdbMi &name, names.children()) {
|
||||
ThreadData thread;
|
||||
thread.id = ThreadId(name["id"].toInt());
|
||||
thread.name = decodeData(name["value"].data(),
|
||||
debuggerEncoding(name["valueencoded"].data()));
|
||||
thread.name = decodeData(name["value"].data(), name["valueencoded"].data());
|
||||
handler->updateThread(thread);
|
||||
}
|
||||
updateViews();
|
||||
|
||||
@@ -122,7 +122,6 @@ WatchData::WatchData() :
|
||||
id(WatchData::InvalidId),
|
||||
state(InitialState),
|
||||
editformat(StopDisplay),
|
||||
editencoding(Unencoded8Bit),
|
||||
address(0),
|
||||
origaddr(0),
|
||||
size(0),
|
||||
@@ -389,9 +388,9 @@ QByteArray WatchData::hexAddress() const
|
||||
void WatchData::updateValue(const GdbMi &item)
|
||||
{
|
||||
GdbMi value = item["value"];
|
||||
DebuggerEncoding encoding = debuggerEncoding(item["valueencoded"].data());
|
||||
if (value.isValid() || encoding != Unencoded8Bit) {
|
||||
setValue(decodeData(value.data(), encoding));
|
||||
GdbMi encoding = item["valueencoded"];
|
||||
if (value.isValid() || encoding.isValid()) {
|
||||
setValue(decodeData(value.data(), encoding.data()));
|
||||
} else {
|
||||
setValueNeeded();
|
||||
}
|
||||
@@ -483,48 +482,51 @@ void decodeArrayHelper(std::function<void(const WatchData &)> itemHandler, const
|
||||
}
|
||||
|
||||
void decodeArrayData(std::function<void(const WatchData &)> itemHandler, const WatchData &tmplate,
|
||||
const QByteArray &rawData, int encoding)
|
||||
const QByteArray &rawData, const DebuggerEncoding &encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
case Hex2EncodedInt1:
|
||||
decodeArrayHelper<signed char>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedInt2:
|
||||
decodeArrayHelper<short>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedInt4:
|
||||
decodeArrayHelper<int>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedInt8:
|
||||
decodeArrayHelper<qint64>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt1:
|
||||
decodeArrayHelper<uchar>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt2:
|
||||
decodeArrayHelper<ushort>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt4:
|
||||
decodeArrayHelper<uint>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt8:
|
||||
decodeArrayHelper<quint64>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedFloat4:
|
||||
decodeArrayHelper<float>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
case Hex2EncodedFloat8:
|
||||
decodeArrayHelper<double>(itemHandler, tmplate, rawData);
|
||||
break;
|
||||
default:
|
||||
qDebug() << "ENCODING ERROR: " << encoding;
|
||||
switch (encoding.type) {
|
||||
case DebuggerEncoding::HexEncodedSignedInteger:
|
||||
switch (encoding.size) {
|
||||
case 1:
|
||||
return decodeArrayHelper<signed char>(itemHandler, tmplate, rawData);
|
||||
case 2:
|
||||
return decodeArrayHelper<short>(itemHandler, tmplate, rawData);
|
||||
case 4:
|
||||
return decodeArrayHelper<int>(itemHandler, tmplate, rawData);
|
||||
case 8:
|
||||
return decodeArrayHelper<qint64>(itemHandler, tmplate, rawData);
|
||||
}
|
||||
break;
|
||||
case DebuggerEncoding::HexEncodedUnsignedInteger:
|
||||
switch (encoding.size) {
|
||||
case 1:
|
||||
return decodeArrayHelper<uchar>(itemHandler, tmplate, rawData);
|
||||
case 2:
|
||||
return decodeArrayHelper<ushort>(itemHandler, tmplate, rawData);
|
||||
case 4:
|
||||
return decodeArrayHelper<uint>(itemHandler, tmplate, rawData);
|
||||
case 8:
|
||||
return decodeArrayHelper<quint64>(itemHandler, tmplate, rawData);
|
||||
}
|
||||
break;
|
||||
case DebuggerEncoding::HexEncodedFloat:
|
||||
switch (encoding.size) {
|
||||
case 4:
|
||||
return decodeArrayHelper<float>(itemHandler, tmplate, rawData);
|
||||
case 8:
|
||||
return decodeArrayHelper<double>(itemHandler, tmplate, rawData);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
qDebug() << "ENCODING ERROR: " << encoding.toString();
|
||||
}
|
||||
|
||||
void parseChildrenData(const WatchData &data0, const GdbMi &item,
|
||||
std::function<void(const WatchData &)> itemHandler,
|
||||
std::function<void(const WatchData &, const GdbMi &)> childHandler,
|
||||
std::function<void(const WatchData &childTemplate, const QByteArray &encodedData, int encoding)> arrayDecoder)
|
||||
std::function<void(const WatchData &childTemplate, const QByteArray &encodedData,
|
||||
const DebuggerEncoding &encoding)> arrayDecoder)
|
||||
{
|
||||
WatchData data = data0;
|
||||
data.setChildrenUnneeded();
|
||||
@@ -535,7 +537,7 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
|
||||
|
||||
data.editvalue = item["editvalue"].data();
|
||||
data.editformat = DebuggerDisplay(item["editformat"].toInt());
|
||||
data.editencoding = DebuggerEncoding(item["editencoding"].toInt());
|
||||
data.editencoding = DebuggerEncoding(item["editencoding"].data());
|
||||
|
||||
GdbMi mi = item["valueelided"];
|
||||
if (mi.isValid())
|
||||
@@ -582,7 +584,7 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
|
||||
|
||||
mi = item["arraydata"];
|
||||
if (mi.isValid()) {
|
||||
int encoding = item["arrayencoding"].toInt();
|
||||
DebuggerEncoding encoding(item["arrayencoding"].data());
|
||||
childtemplate.iname = data.iname + '.';
|
||||
childtemplate.address = addressBase;
|
||||
arrayDecoder(childtemplate, mi.data(), encoding);
|
||||
@@ -611,8 +613,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, DebuggerEncoding(encoding));
|
||||
data1.name = decodeData(key, child["keyencoded"].data());
|
||||
}
|
||||
childHandler(data1, child);
|
||||
}
|
||||
@@ -629,7 +630,7 @@ void parseWatchData(const WatchData &data0, const GdbMi &input,
|
||||
parseWatchData(innerData, innerInput, list);
|
||||
};
|
||||
auto arrayDecoder = [itemHandler](const WatchData &childTemplate,
|
||||
const QByteArray &encodedData, int encoding) {
|
||||
const QByteArray &encodedData, const DebuggerEncoding &encoding) {
|
||||
decodeArrayData(itemHandler, childTemplate, encodedData, encoding);
|
||||
};
|
||||
|
||||
@@ -648,43 +649,52 @@ void readNumericVectorHelper(std::vector<double> *v, const QByteArray &ba)
|
||||
(*v)[i] = static_cast<double>(p[i]);
|
||||
}
|
||||
|
||||
void readNumericVector(std::vector<double> *v, const QByteArray &rawData, DebuggerEncoding encoding)
|
||||
void readNumericVector(std::vector<double> *v, const QByteArray &rawData, const DebuggerEncoding &encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
case Hex2EncodedInt1:
|
||||
switch (encoding.type) {
|
||||
case DebuggerEncoding::HexEncodedSignedInteger:
|
||||
switch (encoding.size) {
|
||||
case 1:
|
||||
readNumericVectorHelper<signed char>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedInt2:
|
||||
return;
|
||||
case 2:
|
||||
readNumericVectorHelper<short>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedInt4:
|
||||
return;
|
||||
case 4:
|
||||
readNumericVectorHelper<int>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedInt8:
|
||||
return;
|
||||
case 8:
|
||||
readNumericVectorHelper<qint64>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt1:
|
||||
readNumericVectorHelper<uchar>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt2:
|
||||
readNumericVectorHelper<ushort>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt4:
|
||||
readNumericVectorHelper<uint>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedUInt8:
|
||||
readNumericVectorHelper<quint64>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedFloat4:
|
||||
readNumericVectorHelper<float>(v, rawData);
|
||||
break;
|
||||
case Hex2EncodedFloat8:
|
||||
readNumericVectorHelper<double>(v, rawData);
|
||||
break;
|
||||
default:
|
||||
qDebug() << "ENCODING ERROR: " << encoding;
|
||||
return;
|
||||
}
|
||||
|
||||
case DebuggerEncoding::HexEncodedUnsignedInteger:
|
||||
switch (encoding.size) {
|
||||
case 1:
|
||||
readNumericVectorHelper<uchar>(v, rawData);
|
||||
return;
|
||||
case 2:
|
||||
readNumericVectorHelper<ushort>(v, rawData);
|
||||
return;
|
||||
case 4:
|
||||
readNumericVectorHelper<uint>(v, rawData);
|
||||
return;
|
||||
case 8:
|
||||
readNumericVectorHelper<quint64>(v, rawData);
|
||||
return;
|
||||
}
|
||||
case DebuggerEncoding::HexEncodedFloat:
|
||||
switch (encoding.size) {
|
||||
case 4:
|
||||
readNumericVectorHelper<float>(v, rawData);
|
||||
return;
|
||||
case 8:
|
||||
readNumericVectorHelper<double>(v, rawData);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
qDebug() << "ENCODING ERROR: " << encoding.toString();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -127,18 +127,16 @@ public:
|
||||
void decodeArrayData(std::function<void(const WatchData &)> itemHandler,
|
||||
const WatchData &tmplate,
|
||||
const QByteArray &rawData,
|
||||
int encoding);
|
||||
const DebuggerEncoding &encoding);
|
||||
|
||||
void readNumericVector(std::vector<double> *,
|
||||
const QByteArray &rawData,
|
||||
DebuggerEncoding encoding);
|
||||
const DebuggerEncoding &encoding);
|
||||
|
||||
void parseChildrenData(const WatchData &parent, const GdbMi &child,
|
||||
std::function<void(const WatchData &)> itemHandler,
|
||||
std::function<void(const WatchData &, const GdbMi &)> childHandler,
|
||||
std::function<void(const WatchData &childTemplate,
|
||||
const QByteArray &encodedData,
|
||||
int encoding)> arrayDecoder);
|
||||
std::function<void(const WatchData &, const QByteArray &, const DebuggerEncoding &)> arrayDecoder);
|
||||
|
||||
void parseWatchData(const WatchData &parent, const GdbMi &child,
|
||||
QList<WatchData> *insertions);
|
||||
|
||||
@@ -1788,7 +1788,7 @@ void WatchItem::parseWatchData(const GdbMi &input)
|
||||
};
|
||||
|
||||
auto arrayDecoder = [itemAdder](const WatchData &childTemplate,
|
||||
const QByteArray &encodedData, int encoding) {
|
||||
const QByteArray &encodedData, const DebuggerEncoding &encoding) {
|
||||
decodeArrayData(itemAdder, childTemplate, encodedData, encoding);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user