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:
hjk
2015-12-11 13:28:21 +01:00
parent 74b33929d8
commit c2bf384ac2
19 changed files with 404 additions and 570 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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):

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */)

View File

@@ -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,

View File

@@ -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

View File

@@ -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,

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
};