forked from qt-creator/qt-creator
Debugger: Re-organize passing of display formats
The current setup (dumper->gui: list of descriptions, gui->dumper: index in list) is fragile and not easily i18n'able. Go with an enum based approach now. Change-Id: Ie78c596065a8b2ba87ad725274da29d4be3a6da4 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -67,9 +67,15 @@ StartRemoteProcess, \
|
|||||||
|
|
||||||
|
|
||||||
# Known special formats. Keep in sync with DisplayFormat in watchhandler.h
|
# Known special formats. Keep in sync with DisplayFormat in watchhandler.h
|
||||||
KnownDumperFormatBase, \
|
AutomaticFormat, \
|
||||||
|
RawFormat, \
|
||||||
|
SimpleFormat, \
|
||||||
|
EnhancedFormat, \
|
||||||
|
SeparateFormat, \
|
||||||
Latin1StringFormat, \
|
Latin1StringFormat, \
|
||||||
|
SeparateLatin1StringFormat, \
|
||||||
Utf8StringFormat, \
|
Utf8StringFormat, \
|
||||||
|
SeparateUtf8StringFormat, \
|
||||||
Local8BitStringFormat, \
|
Local8BitStringFormat, \
|
||||||
Utf16StringFormat, \
|
Utf16StringFormat, \
|
||||||
Ucs4StringFormat, \
|
Ucs4StringFormat, \
|
||||||
@@ -77,9 +83,11 @@ Array10Format, \
|
|||||||
Array100Format, \
|
Array100Format, \
|
||||||
Array1000Format, \
|
Array1000Format, \
|
||||||
Array10000Format, \
|
Array10000Format, \
|
||||||
SeparateLatin1StringFormat, \
|
ArrayPlotFormat, \
|
||||||
SeparateUtf8StringFormat \
|
CompactMapFormat, \
|
||||||
= range(100, 112)
|
DirectQListStorageFormat, \
|
||||||
|
IndirectQListStorageFormat, \
|
||||||
|
= range(0, 20)
|
||||||
|
|
||||||
# Breakpoints. Keep synchronized with BreakpointType in breakpoint.h
|
# Breakpoints. Keep synchronized with BreakpointType in breakpoint.h
|
||||||
UnknownType, \
|
UnknownType, \
|
||||||
@@ -171,10 +179,10 @@ if hasSubprocess and hasPlot:
|
|||||||
|
|
||||||
def arrayForms():
|
def arrayForms():
|
||||||
global hasPlot
|
global hasPlot
|
||||||
return "Normal,Plot" if hasPlot else "Normal"
|
return [ArrayPlotFormat] if hasPlot else []
|
||||||
|
|
||||||
def mapForms():
|
def mapForms():
|
||||||
return "Normal,Compact"
|
return [CompactMapFormat]
|
||||||
|
|
||||||
|
|
||||||
class ReportItem:
|
class ReportItem:
|
||||||
@@ -583,12 +591,13 @@ class DumperBase:
|
|||||||
elided, shown = self.computeLimit(size, limit)
|
elided, shown = self.computeLimit(size, limit)
|
||||||
return elided, self.readMemory(data, shown)
|
return elided, self.readMemory(data, shown)
|
||||||
|
|
||||||
def putStdStringHelper(self, data, size, charSize, format = None):
|
def putStdStringHelper(self, data, size, charSize, displayFormat = AutomaticFormat):
|
||||||
bytelen = size * charSize
|
bytelen = size * charSize
|
||||||
elided, shown = self.computeLimit(bytelen, self.displayStringLimit)
|
elided, shown = self.computeLimit(bytelen, self.displayStringLimit)
|
||||||
mem = self.readMemory(data, shown)
|
mem = self.readMemory(data, shown)
|
||||||
if charSize == 1:
|
if charSize == 1:
|
||||||
if format == 1 or format == 2:
|
if displayFormat == Latin1StringFormat \
|
||||||
|
or displayFormat == SeparateLatin1StringFormat:
|
||||||
encodingType = Hex2EncodedLatin1
|
encodingType = Hex2EncodedLatin1
|
||||||
else:
|
else:
|
||||||
encodingType = Hex2EncodedUtf8
|
encodingType = Hex2EncodedUtf8
|
||||||
@@ -603,9 +612,11 @@ class DumperBase:
|
|||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
self.putValue(mem, encodingType, elided=elided)
|
self.putValue(mem, encodingType, elided=elided)
|
||||||
|
|
||||||
if format == 1 or format == 3:
|
if displayFormat == Latin1StringFormat \
|
||||||
|
or displayFormat == Utf8StringFormat:
|
||||||
self.putDisplay(StopDisplay)
|
self.putDisplay(StopDisplay)
|
||||||
elif format == 2 or format == 4:
|
elif displayFormat == SeparateLatin1StringFormat \
|
||||||
|
or displayFormat == SeparateUtf8StringFormat:
|
||||||
self.putField("editformat", displayType)
|
self.putField("editformat", displayType)
|
||||||
elided, shown = self.computeLimit(bytelen, 100000)
|
elided, shown = self.computeLimit(bytelen, 100000)
|
||||||
self.putField("editvalue", self.readMemory(data, shown))
|
self.putField("editvalue", self.readMemory(data, shown))
|
||||||
@@ -801,9 +812,8 @@ class DumperBase:
|
|||||||
self.putFields(value, dumpBase)
|
self.putFields(value, dumpBase)
|
||||||
|
|
||||||
def isMapCompact(self, keyType, valueType):
|
def isMapCompact(self, keyType, valueType):
|
||||||
format = self.currentItemFormat()
|
if self.currentItemFormat() == CompactMapFormat:
|
||||||
if format == 2:
|
return True
|
||||||
return True # Compact.
|
|
||||||
return self.isSimpleType(keyType) and self.isSimpleType(valueType)
|
return self.isSimpleType(keyType) and self.isSimpleType(valueType)
|
||||||
|
|
||||||
|
|
||||||
@@ -920,13 +930,13 @@ class DumperBase:
|
|||||||
except:
|
except:
|
||||||
p = None
|
p = None
|
||||||
|
|
||||||
itemFormat = self.currentItemFormat()
|
displayFormat = self.currentItemFormat()
|
||||||
n = int(arrayType.sizeof / ts)
|
n = int(arrayType.sizeof / ts)
|
||||||
|
|
||||||
if p and self.tryPutSimpleFormattedPointer(p, str(arrayType), itemFormat, arrayType.sizeof):
|
if p and self.tryPutSimpleFormattedPointer(p, str(arrayType), displayFormat, arrayType.sizeof):
|
||||||
self.putNumChild(n)
|
self.putNumChild(n)
|
||||||
pass
|
pass
|
||||||
elif itemFormat is None:
|
elif displayFormat is None:
|
||||||
innerTypeName = str(innerType.unqualified())
|
innerTypeName = str(innerType.unqualified())
|
||||||
blob = self.readMemory(self.addressOf(value), arrayType.sizeof)
|
blob = self.readMemory(self.addressOf(value), arrayType.sizeof)
|
||||||
if innerTypeName == "char":
|
if innerTypeName == "char":
|
||||||
@@ -969,6 +979,31 @@ class DumperBase:
|
|||||||
pass
|
pass
|
||||||
return str(addr)
|
return str(addr)
|
||||||
|
|
||||||
|
def tryPutPrettyItem(self, typeName, value):
|
||||||
|
if self.useFancy and self.currentItemFormat() != RawFormat:
|
||||||
|
self.putType(typeName)
|
||||||
|
|
||||||
|
nsStrippedType = self.stripNamespaceFromType(typeName)\
|
||||||
|
.replace("::", "__")
|
||||||
|
|
||||||
|
# The following block is only needed for D.
|
||||||
|
if nsStrippedType.startswith("_A"):
|
||||||
|
# DMD v2.058 encodes string[] as _Array_uns long long.
|
||||||
|
# With spaces.
|
||||||
|
if nsStrippedType.startswith("_Array_"):
|
||||||
|
qdump_Array(self, value)
|
||||||
|
return True
|
||||||
|
if nsStrippedType.startswith("_AArray_"):
|
||||||
|
qdump_AArray(self, value)
|
||||||
|
return True
|
||||||
|
|
||||||
|
dumper = self.qqDumpers.get(nsStrippedType)
|
||||||
|
if not dumper is None:
|
||||||
|
dumper(self, value)
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def tryPutArrayContents(self, base, n, innerType):
|
def tryPutArrayContents(self, base, n, innerType):
|
||||||
enc = self.simpleEncoding(innerType)
|
enc = self.simpleEncoding(innerType)
|
||||||
if not enc:
|
if not enc:
|
||||||
@@ -991,8 +1026,8 @@ class DumperBase:
|
|||||||
data = self.readMemory(base, shown)
|
data = self.readMemory(base, shown)
|
||||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||||
|
|
||||||
def putDisplay(self, format, value = None, cmd = None):
|
def putDisplay(self, editFormat, value = None, cmd = None):
|
||||||
self.put('editformat="%s",' % format)
|
self.put('editformat="%s",' % editFormat)
|
||||||
if cmd is None:
|
if cmd is None:
|
||||||
if not value is None:
|
if not value is None:
|
||||||
self.put('editvalue="%s",' % value)
|
self.put('editvalue="%s",' % value)
|
||||||
@@ -1000,8 +1035,8 @@ class DumperBase:
|
|||||||
self.put('editvalue="%s|%s",' % (cmd, value))
|
self.put('editvalue="%s|%s",' % (cmd, value))
|
||||||
|
|
||||||
# This is shared by pointer and array formatting.
|
# This is shared by pointer and array formatting.
|
||||||
def tryPutSimpleFormattedPointer(self, value, typeName, itemFormat, limit):
|
def tryPutSimpleFormattedPointer(self, value, typeName, displayFormat, limit):
|
||||||
if itemFormat == None and typeName == "char":
|
if displayFormat == AutomaticFormat and typeName == "char":
|
||||||
# Use Latin1 as default for char *.
|
# Use Latin1 as default for char *.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||||
@@ -1009,56 +1044,49 @@ class DumperBase:
|
|||||||
self.putDisplay(StopDisplay)
|
self.putDisplay(StopDisplay)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if itemFormat == Latin1StringFormat:
|
if displayFormat == Latin1StringFormat:
|
||||||
# Explicitly requested Latin1 formatting.
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||||
self.putDisplay(StopDisplay)
|
self.putDisplay(StopDisplay)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if itemFormat == SeparateLatin1StringFormat:
|
if displayFormat == SeparateLatin1StringFormat:
|
||||||
# Explicitly requested Latin1 formatting in separate window.
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||||
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
self.putValue(data, Hex2EncodedLatin1, elided=elided)
|
||||||
self.putDisplay(DisplayLatin1String, data)
|
self.putDisplay(DisplayLatin1String, data)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if itemFormat == Utf8StringFormat:
|
if displayFormat == Utf8StringFormat:
|
||||||
# Explicitly requested UTF-8 formatting.
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||||
self.putValue(data, Hex2EncodedUtf8, elided=elided)
|
self.putValue(data, Hex2EncodedUtf8, elided=elided)
|
||||||
self.putDisplay(StopDisplay)
|
self.putDisplay(StopDisplay)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if itemFormat == SeparateUtf8StringFormat:
|
if displayFormat == SeparateUtf8StringFormat:
|
||||||
# Explicitly requested UTF-8 formatting in separate window.
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||||
self.putValue(data, Hex2EncodedUtf8, elided=elided)
|
self.putValue(data, Hex2EncodedUtf8, elided=elided)
|
||||||
self.putDisplay(DisplayUtf8String, data)
|
self.putDisplay(DisplayUtf8String, data)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if itemFormat == Local8BitStringFormat:
|
if displayFormat == Local8BitStringFormat:
|
||||||
# Explicitly requested local 8 bit formatting.
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 1, limit)
|
(elided, data) = self.encodeCArray(value, 1, limit)
|
||||||
self.putValue(data, Hex2EncodedLocal8Bit, elided=elided)
|
self.putValue(data, Hex2EncodedLocal8Bit, elided=elided)
|
||||||
self.putDisplay(StopDisplay)
|
self.putDisplay(StopDisplay)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if itemFormat == Utf16StringFormat:
|
if displayFormat == Utf16StringFormat:
|
||||||
# Explicitly requested UTF-16 formatting.
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 2, limit)
|
(elided, data) = self.encodeCArray(value, 2, limit)
|
||||||
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
|
||||||
self.putDisplay(StopDisplay)
|
self.putDisplay(StopDisplay)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if itemFormat == Ucs4StringFormat:
|
if displayFormat == Ucs4StringFormat:
|
||||||
# Explicitly requested UCS-4 formatting.
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, data) = self.encodeCArray(value, 4, limit)
|
(elided, data) = self.encodeCArray(value, 4, limit)
|
||||||
self.putValue(data, Hex8EncodedLittleEndian, elided=elided)
|
self.putValue(data, Hex8EncodedLittleEndian, elided=elided)
|
||||||
@@ -1091,16 +1119,16 @@ class DumperBase:
|
|||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
format = self.currentItemFormat(value.type)
|
displayFormat = self.currentItemFormat(value.type)
|
||||||
|
|
||||||
if innerTypeName == "void":
|
if innerTypeName == "void":
|
||||||
#warn("VOID POINTER: %s" % format)
|
#warn("VOID POINTER: %s" % displayFormat)
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(str(value))
|
self.putValue(str(value))
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
if format == 0:
|
if displayFormat == RawFormat:
|
||||||
# Explicitly requested bald pointer.
|
# Explicitly requested bald pointer.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putValue(self.hexencode(str(value)), Hex2EncodedUtf8WithoutQuotes)
|
self.putValue(self.hexencode(str(value)), Hex2EncodedUtf8WithoutQuotes)
|
||||||
@@ -1112,16 +1140,15 @@ class DumperBase:
|
|||||||
return
|
return
|
||||||
|
|
||||||
limit = self.displayStringLimit
|
limit = self.displayStringLimit
|
||||||
if format == DisplayLatin1String or format == DisplayUtf8String:
|
if displayFormat == SeparateLatin1StringFormat \
|
||||||
|
or displayFormat == SeparateUtf8StringFormat:
|
||||||
limit = 1000000
|
limit = 1000000
|
||||||
if self.tryPutSimpleFormattedPointer(value, typeName, format, limit):
|
if self.tryPutSimpleFormattedPointer(value, typeName, displayFormat, limit):
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not format is None \
|
if Array10Format <= displayFormat and displayFormat <= Array1000Format:
|
||||||
and format >= Array10Format and format <= Array1000Format:
|
n = (10, 100, 1000, 10000)[displayFormat - Array10Format]
|
||||||
# Explicitly requested formatting as array of n items.
|
|
||||||
n = (10, 100, 1000, 10000)[format - Array10Format]
|
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
self.putItemCount(n)
|
self.putItemCount(n)
|
||||||
self.putArrayData(value, n, innerType)
|
self.putArrayData(value, n, innerType)
|
||||||
@@ -1141,9 +1168,7 @@ class DumperBase:
|
|||||||
#warn("AUTODEREF: %s" % self.autoDerefPointers)
|
#warn("AUTODEREF: %s" % self.autoDerefPointers)
|
||||||
#warn("INAME: %s" % self.currentIName)
|
#warn("INAME: %s" % self.currentIName)
|
||||||
if self.autoDerefPointers or self.currentIName.endswith('.this'):
|
if self.autoDerefPointers or self.currentIName.endswith('.this'):
|
||||||
## Generic pointer type with format None
|
# Generic pointer type with AutomaticFormat.
|
||||||
#warn("GENERIC AUTODEREF POINTER: %s AT %s TO %s"
|
|
||||||
# % (type, value.address, innerTypeName))
|
|
||||||
# Never dereference char types.
|
# Never dereference char types.
|
||||||
if innerTypeName != "char" \
|
if innerTypeName != "char" \
|
||||||
and innerTypeName != "signed char" \
|
and innerTypeName != "signed char" \
|
||||||
@@ -1491,13 +1516,13 @@ class DumperBase:
|
|||||||
return typeName == "QStringList" and self.qtVersion() >= 0x050000
|
return typeName == "QStringList" and self.qtVersion() >= 0x050000
|
||||||
|
|
||||||
def currentItemFormat(self, type = None):
|
def currentItemFormat(self, type = None):
|
||||||
format = self.formats.get(self.currentIName)
|
displayFormat = self.formats.get(self.currentIName, AutomaticFormat)
|
||||||
if format is None:
|
if displayFormat == AutomaticFormat:
|
||||||
if type is None:
|
if type is None:
|
||||||
type = self.currentType.value
|
type = self.currentType.value
|
||||||
needle = self.stripForFormat(str(type))
|
needle = self.stripForFormat(str(type))
|
||||||
format = self.typeformats.get(needle)
|
displayFormat = self.typeformats.get(needle, AutomaticFormat)
|
||||||
return format
|
return displayFormat
|
||||||
|
|
||||||
def putArrayData(self, base, n, innerType = None,
|
def putArrayData(self, base, n, innerType = None,
|
||||||
childNumChild = None, maxNumChild = 10000):
|
childNumChild = None, maxNumChild = 10000):
|
||||||
@@ -1511,19 +1536,19 @@ class DumperBase:
|
|||||||
i = toInteger(i)
|
i = toInteger(i)
|
||||||
self.putSubItem(i, (base + i).dereference())
|
self.putSubItem(i, (base + i).dereference())
|
||||||
|
|
||||||
def putArrayItem(self, name, addr, n, typeName, plotFormat = 2):
|
def putArrayItem(self, name, addr, n, typeName):
|
||||||
with SubItem(self, name):
|
with SubItem(self, name):
|
||||||
self.putEmptyValue()
|
self.putEmptyValue()
|
||||||
self.putType("%s [%d]" % (typeName, n))
|
self.putType("%s [%d]" % (typeName, n))
|
||||||
self.putArrayData(addr, n, self.lookupType(typeName))
|
self.putArrayData(addr, n, self.lookupType(typeName))
|
||||||
self.putAddress(addr)
|
self.putAddress(addr)
|
||||||
|
|
||||||
def putPlotData(self, base, n, typeobj, plotFormat = 2):
|
def putPlotData(self, base, n, typeobj):
|
||||||
if self.isExpanded():
|
if self.isExpanded():
|
||||||
self.putArrayData(base, n, typeobj)
|
self.putArrayData(base, n, typeobj)
|
||||||
if hasPlot:
|
if hasPlot:
|
||||||
if self.isSimpleType(typeobj):
|
if self.isSimpleType(typeobj):
|
||||||
show = self.currentItemFormat() == plotFormat
|
show = self.currentItemFormat() == ArrayPlotFormat
|
||||||
iname = self.currentIName
|
iname = self.currentIName
|
||||||
data = []
|
data = []
|
||||||
if show:
|
if show:
|
||||||
@@ -1688,15 +1713,13 @@ class DumperBase:
|
|||||||
if funcname.startswith("qdump__"):
|
if funcname.startswith("qdump__"):
|
||||||
typename = funcname[7:]
|
typename = funcname[7:]
|
||||||
self.qqDumpers[typename] = function
|
self.qqDumpers[typename] = function
|
||||||
self.qqFormats[typename] = self.qqFormats.get(typename, "")
|
self.qqFormats[typename] = self.qqFormats.get(typename, [])
|
||||||
elif funcname.startswith("qform__"):
|
elif funcname.startswith("qform__"):
|
||||||
typename = funcname[7:]
|
typename = funcname[7:]
|
||||||
formats = ""
|
|
||||||
try:
|
try:
|
||||||
formats = function()
|
self.qqFormats[typename] = function()
|
||||||
except:
|
except:
|
||||||
pass
|
self.qqFormats[typename] = []
|
||||||
self.qqFormats[typename] = formats
|
|
||||||
elif funcname.startswith("qedit__"):
|
elif funcname.startswith("qedit__"):
|
||||||
typename = funcname[7:]
|
typename = funcname[7:]
|
||||||
try:
|
try:
|
||||||
@@ -1721,15 +1744,14 @@ class DumperBase:
|
|||||||
|
|
||||||
msg = "dumpers=["
|
msg = "dumpers=["
|
||||||
for key, value in self.qqFormats.items():
|
for key, value in self.qqFormats.items():
|
||||||
if key in self.qqEditable:
|
editable = ',editable="true"' if key in self.qqEditable else ''
|
||||||
msg += '{type="%s",formats="%s",editable="true"},' % (key, value)
|
formats = (',formats=\"%s\"' % str(value)[1:-1]) if len(value) else ''
|
||||||
else:
|
msg += '{type="%s"%s%s},' % (key, editable, formats)
|
||||||
msg += '{type="%s",formats="%s"},' % (key, value)
|
|
||||||
msg += ']'
|
msg += ']'
|
||||||
self.reportDumpers(msg)
|
self.reportDumpers(msg)
|
||||||
|
|
||||||
def reportDumpers(self, msg):
|
def reportDumpers(self, msg):
|
||||||
raise NotImplementedError # Pure
|
raise NotImplementedError
|
||||||
|
|
||||||
def reloadDumpers(self, args):
|
def reloadDumpers(self, args):
|
||||||
for mod in self.dumpermodules:
|
for mod in self.dumpermodules:
|
||||||
|
@@ -1075,35 +1075,8 @@ class Dumper(DumperBase):
|
|||||||
self.putItem(self.expensiveDowncast(value), False)
|
self.putItem(self.expensiveDowncast(value), False)
|
||||||
return
|
return
|
||||||
|
|
||||||
format = self.currentItemFormat(typeName)
|
if self.tryPutPrettyItem(typeName, value):
|
||||||
|
return
|
||||||
if self.useFancy and (format is None or format >= 1):
|
|
||||||
self.putType(typeName)
|
|
||||||
|
|
||||||
nsStrippedType = self.stripNamespaceFromType(typeName)\
|
|
||||||
.replace("::", "__")
|
|
||||||
|
|
||||||
# The following block is only needed for D.
|
|
||||||
if nsStrippedType.startswith("_A"):
|
|
||||||
# DMD v2.058 encodes string[] as _Array_uns long long.
|
|
||||||
# With spaces.
|
|
||||||
if nsStrippedType.startswith("_Array_"):
|
|
||||||
qdump_Array(self, value)
|
|
||||||
return
|
|
||||||
if nsStrippedType.startswith("_AArray_"):
|
|
||||||
qdump_AArray(self, value)
|
|
||||||
return
|
|
||||||
|
|
||||||
#warn(" STRIPPED: %s" % nsStrippedType)
|
|
||||||
#warn(" DUMPERS: %s" % self.qqDumpers)
|
|
||||||
#warn(" DUMPERS: %s" % (nsStrippedType in self.qqDumpers))
|
|
||||||
dumper = self.qqDumpers.get(nsStrippedType, None)
|
|
||||||
if not dumper is None:
|
|
||||||
if tryDynamic:
|
|
||||||
dumper(self, self.expensiveDowncast(value))
|
|
||||||
else:
|
|
||||||
dumper(self, value)
|
|
||||||
return
|
|
||||||
|
|
||||||
# D arrays, gdc compiled.
|
# D arrays, gdc compiled.
|
||||||
if typeName.endswith("[]"):
|
if typeName.endswith("[]"):
|
||||||
|
@@ -1063,15 +1063,8 @@ class Dumper(DumperBase):
|
|||||||
|
|
||||||
#warn("VALUE: %s" % value)
|
#warn("VALUE: %s" % value)
|
||||||
#warn("FANCY: %s" % self.useFancy)
|
#warn("FANCY: %s" % self.useFancy)
|
||||||
if self.useFancy:
|
if self.tryPutPrettyItem(typeName, value):
|
||||||
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
|
return
|
||||||
#warn("STRIPPED: %s" % stripped)
|
|
||||||
#warn("DUMPABLE: %s" % (stripped in self.qqDumpers))
|
|
||||||
if stripped in self.qqDumpers:
|
|
||||||
self.putType(typeName)
|
|
||||||
self.context = value
|
|
||||||
self.qqDumpers[stripped](self, value)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Normal value
|
# Normal value
|
||||||
#numchild = 1 if value.MightHaveChildren() else 0
|
#numchild = 1 if value.MightHaveChildren() else 0
|
||||||
|
@@ -53,24 +53,25 @@ def qdump__QAtomicPointer(d, value):
|
|||||||
d.putSubItem("_q_value", q.dereference())
|
d.putSubItem("_q_value", q.dereference())
|
||||||
|
|
||||||
def qform__QByteArray():
|
def qform__QByteArray():
|
||||||
return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window"
|
return [Latin1StringFormat, SeparateLatin1StringFormat,
|
||||||
|
Utf8StringFormat, SeparateUtf8StringFormat ]
|
||||||
|
|
||||||
def qdump__QByteArray(d, value):
|
def qdump__QByteArray(d, value):
|
||||||
data, size, alloc = d.byteArrayData(value)
|
data, size, alloc = d.byteArrayData(value)
|
||||||
d.putNumChild(size)
|
d.putNumChild(size)
|
||||||
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
|
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
|
||||||
format = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
if format == 1 or format is None:
|
if displayFormat == AutomaticFormat or displayFormat == Latin1StringFormat:
|
||||||
d.putDisplay(StopDisplay)
|
d.putDisplay(StopDisplay)
|
||||||
d.putValue(p, Hex2EncodedLatin1, elided=elided)
|
d.putValue(p, Hex2EncodedLatin1, elided=elided)
|
||||||
elif format == 2:
|
elif displayFormat == SeparateLatin1StringFormat:
|
||||||
d.putValue(p, Hex2EncodedLatin1, elided=elided)
|
d.putValue(p, Hex2EncodedLatin1, elided=elided)
|
||||||
d.putField("editformat", DisplayLatin1String)
|
d.putField("editformat", DisplayLatin1String)
|
||||||
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
|
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
|
||||||
elif format == 3:
|
elif displayFormat == Utf8StringFormat:
|
||||||
d.putDisplay(StopDisplay)
|
d.putDisplay(StopDisplay)
|
||||||
d.putValue(p, Hex2EncodedUtf8, elided=elided)
|
d.putValue(p, Hex2EncodedUtf8, elided=elided)
|
||||||
elif format == 4:
|
elif displayFormat == SeparateUtf8StringFormat:
|
||||||
d.putValue(p, Hex2EncodedUtf8, elided=elided)
|
d.putValue(p, Hex2EncodedUtf8, elided=elided)
|
||||||
d.putField("editformat", DisplayUtf8String)
|
d.putField("editformat", DisplayUtf8String)
|
||||||
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
|
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
|
||||||
@@ -92,14 +93,14 @@ def qdump__QChar(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qform__QAbstractItemModel():
|
def qform__QAbstractItemModel():
|
||||||
return "Normal,Enhanced"
|
return [SimpleFormat, EnhancedFormat]
|
||||||
|
|
||||||
def qdump__QAbstractItemModel(d, value):
|
def qdump__QAbstractItemModel(d, value):
|
||||||
format = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
if format == 1:
|
if displayFormat == SimpleFormat:
|
||||||
d.putPlainChildren(value)
|
d.putPlainChildren(value)
|
||||||
return
|
return
|
||||||
#format == 2:
|
#displayFormat == EnhancedFormat:
|
||||||
# Create a default-constructed QModelIndex on the stack.
|
# Create a default-constructed QModelIndex on the stack.
|
||||||
try:
|
try:
|
||||||
ri = d.makeValue(d.qtNamespace() + "QModelIndex", "-1, -1, 0, 0")
|
ri = d.makeValue(d.qtNamespace() + "QModelIndex", "-1, -1, 0, 0")
|
||||||
@@ -134,11 +135,11 @@ def qdump__QAbstractItemModel(d, value):
|
|||||||
#gdb.execute("call free($ri)")
|
#gdb.execute("call free($ri)")
|
||||||
|
|
||||||
def qform__QModelIndex():
|
def qform__QModelIndex():
|
||||||
return "Normal,Enhanced"
|
return [SimpleFormat, EnhancedFormat]
|
||||||
|
|
||||||
def qdump__QModelIndex(d, value):
|
def qdump__QModelIndex(d, value):
|
||||||
format = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
if format == 1:
|
if displayFormat == SimpleFormat:
|
||||||
d.putPlainChildren(value)
|
d.putPlainChildren(value)
|
||||||
return
|
return
|
||||||
r = value["r"]
|
r = value["r"]
|
||||||
@@ -768,7 +769,7 @@ def qdump__QIPv6Address(d, value):
|
|||||||
d.putPlainChildren(c)
|
d.putPlainChildren(c)
|
||||||
|
|
||||||
def qform__QList():
|
def qform__QList():
|
||||||
return "Assume Direct Storage,Assume Indirect Storage"
|
return [DirectQListStorageFormat, IndirectQListStorageFormat]
|
||||||
|
|
||||||
def qdump__QList(d, value):
|
def qdump__QList(d, value):
|
||||||
base = d.extractPointer(value)
|
base = d.extractPointer(value)
|
||||||
@@ -794,10 +795,10 @@ def qdump__QList(d, value):
|
|||||||
# but this data is available neither in the compiled binary nor
|
# but this data is available neither in the compiled binary nor
|
||||||
# in the frontend.
|
# in the frontend.
|
||||||
# So as first approximation only do the 'isLarge' check:
|
# So as first approximation only do the 'isLarge' check:
|
||||||
format = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
if format == 1:
|
if displayFormat == DirectQListStorageFormat:
|
||||||
isInternal = True
|
isInternal = True
|
||||||
elif format == 2:
|
elif displayFormat == IndirectQListStorageFormat:
|
||||||
isInternal = False
|
isInternal = False
|
||||||
else:
|
else:
|
||||||
isInternal = innerSize <= stepSize and d.isMovableType(innerType)
|
isInternal = innerSize <= stepSize and d.isMovableType(innerType)
|
||||||
@@ -818,7 +819,7 @@ def qdump__QList(d, value):
|
|||||||
d.putSubItem(i, x)
|
d.putSubItem(i, x)
|
||||||
|
|
||||||
def qform__QImage():
|
def qform__QImage():
|
||||||
return "Normal,Displayed"
|
return [SimpleFormat, SeparateFormat]
|
||||||
|
|
||||||
def qdump__QImage(d, value):
|
def qdump__QImage(d, value):
|
||||||
# This relies on current QImage layout:
|
# This relies on current QImage layout:
|
||||||
@@ -861,10 +862,10 @@ def qdump__QImage(d, value):
|
|||||||
d.putNumChild(0)
|
d.putNumChild(0)
|
||||||
d.putType("void *")
|
d.putType("void *")
|
||||||
|
|
||||||
format = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
if format == 1:
|
if displayFormat == SimpleFormat:
|
||||||
d.putDisplay(StopDisplay)
|
d.putDisplay(StopDisplay)
|
||||||
elif format == 2:
|
elif displayFormat == SeparateFormat:
|
||||||
# This is critical for performance. Writing to an external
|
# This is critical for performance. Writing to an external
|
||||||
# file using the following is faster when using GDB.
|
# file using the following is faster when using GDB.
|
||||||
# file = tempfile.mkstemp(prefix="gdbpy_")
|
# file = tempfile.mkstemp(prefix="gdbpy_")
|
||||||
@@ -1751,16 +1752,16 @@ def qedit__QString(d, value, data):
|
|||||||
d.setValues(base, "short", [ord(c) for c in data])
|
d.setValues(base, "short", [ord(c) for c in data])
|
||||||
|
|
||||||
def qform__QString():
|
def qform__QString():
|
||||||
return "Inline,Separate Window"
|
return [SimpleFormat, SeparateFormat]
|
||||||
|
|
||||||
def qdump__QString(d, value):
|
def qdump__QString(d, value):
|
||||||
d.putStringValue(value)
|
d.putStringValue(value)
|
||||||
data, size, alloc = d.stringData(value)
|
data, size, alloc = d.stringData(value)
|
||||||
d.putNumChild(size)
|
d.putNumChild(size)
|
||||||
format = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
if format == 1:
|
if displayFormat == SimpleFormat:
|
||||||
d.putDisplay(StopDisplay)
|
d.putDisplay(StopDisplay)
|
||||||
elif format == 2:
|
elif displayFormat == SeparateFormat:
|
||||||
d.putField("editformat", DisplayUtf16String)
|
d.putField("editformat", DisplayUtf16String)
|
||||||
d.putField("editvalue", d.encodeString(value, limit=100000))
|
d.putField("editvalue", d.encodeString(value, limit=100000))
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
@@ -1847,7 +1848,7 @@ def qdump__QTextDocument(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qform__QUrl():
|
def qform__QUrl():
|
||||||
return "Inline,Separate Window"
|
return [SimpleFormat, SeparateFormat]
|
||||||
|
|
||||||
def qdump__QUrl(d, value):
|
def qdump__QUrl(d, value):
|
||||||
if d.qtVersion() < 0x050000:
|
if d.qtVersion() < 0x050000:
|
||||||
@@ -1911,10 +1912,10 @@ def qdump__QUrl(d, value):
|
|||||||
url += path
|
url += path
|
||||||
d.putValue(url, Hex4EncodedLittleEndian)
|
d.putValue(url, Hex4EncodedLittleEndian)
|
||||||
|
|
||||||
format = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
if format == 1:
|
if displayFormat == SimpleFormat:
|
||||||
d.putDisplay(StopDisplay)
|
d.putDisplay(StopDisplay)
|
||||||
elif format == 2:
|
elif displayFormat == SeparateFormat:
|
||||||
d.putField("editformat", DisplayUtf16String)
|
d.putField("editformat", DisplayUtf16String)
|
||||||
d.putField("editvalue", url)
|
d.putField("editvalue", url)
|
||||||
|
|
||||||
|
@@ -398,7 +398,8 @@ def qdump__std____debug__stack(d, value):
|
|||||||
qdump__std__stack(d, value)
|
qdump__std__stack(d, value)
|
||||||
|
|
||||||
def qform__std__string():
|
def qform__std__string():
|
||||||
return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window"
|
return [Latin1StringFormat, SeparateLatin1StringFormat,
|
||||||
|
Utf8StringFormat, SeparateUtf8StringFormat ]
|
||||||
|
|
||||||
def qdump__std__string(d, value):
|
def qdump__std__string(d, value):
|
||||||
qdump__std__stringHelper1(d, value, 1, d.currentItemFormat())
|
qdump__std__stringHelper1(d, value, 1, d.currentItemFormat())
|
||||||
@@ -787,7 +788,7 @@ def qdump__string(d, value):
|
|||||||
qdump__std__string(d, value)
|
qdump__std__string(d, value)
|
||||||
|
|
||||||
def qform__std__wstring():
|
def qform__std__wstring():
|
||||||
return "Inline String,String in Separate Window"
|
return [SimpleFormat, SeparateFormat]
|
||||||
|
|
||||||
def qdump__std__wstring(d, value):
|
def qdump__std__wstring(d, value):
|
||||||
charSize = d.lookupType('wchar_t').sizeof
|
charSize = d.lookupType('wchar_t').sizeof
|
||||||
|
@@ -576,17 +576,21 @@ void CdbEngine::setupEngine()
|
|||||||
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed")
|
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed")
|
||||||
notifyEngineSetupFailed();
|
notifyEngineSetupFailed();
|
||||||
}
|
}
|
||||||
const QString normalFormat = tr("Normal");
|
|
||||||
const QStringList stringFormats = QStringList()
|
DisplayFormats stringFormats;
|
||||||
<< normalFormat << tr("Separate Window");
|
stringFormats.append(SimpleFormat);
|
||||||
|
stringFormats.append(SeparateFormat);
|
||||||
|
|
||||||
WatchHandler *wh = watchHandler();
|
WatchHandler *wh = watchHandler();
|
||||||
wh->addTypeFormats("QString", stringFormats);
|
wh->addTypeFormats("QString", stringFormats);
|
||||||
wh->addTypeFormats("QString *", stringFormats);
|
wh->addTypeFormats("QString *", stringFormats);
|
||||||
wh->addTypeFormats("QByteArray", stringFormats);
|
wh->addTypeFormats("QByteArray", stringFormats);
|
||||||
wh->addTypeFormats("QByteArray *", stringFormats);
|
wh->addTypeFormats("QByteArray *", stringFormats);
|
||||||
wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string
|
wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string
|
||||||
const QStringList imageFormats = QStringList()
|
|
||||||
<< normalFormat << tr("Image");
|
DisplayFormats imageFormats;
|
||||||
|
imageFormats.append(SimpleFormat);
|
||||||
|
imageFormats.append(EnhancedFormat);
|
||||||
wh->addTypeFormats("QImage", imageFormats);
|
wh->addTypeFormats("QImage", imageFormats);
|
||||||
wh->addTypeFormats("QImage *", imageFormats);
|
wh->addTypeFormats("QImage *", imageFormats);
|
||||||
}
|
}
|
||||||
|
@@ -807,7 +807,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addTypeFormats(const QString &type,
|
void addTypeFormats(const QString &type,
|
||||||
const QStringList &typeFormats, int current)
|
const DisplayFormats &typeFormats, int current)
|
||||||
{
|
{
|
||||||
const int row = m_layout->rowCount();
|
const int row = m_layout->rowCount();
|
||||||
int column = 0;
|
int column = 0;
|
||||||
@@ -815,7 +815,8 @@ public:
|
|||||||
m_layout->addWidget(new QLabel(type), row, column++);
|
m_layout->addWidget(new QLabel(type), row, column++);
|
||||||
for (int i = -1; i != typeFormats.size(); ++i) {
|
for (int i = -1; i != typeFormats.size(); ++i) {
|
||||||
QRadioButton *choice = new QRadioButton(this);
|
QRadioButton *choice = new QRadioButton(this);
|
||||||
choice->setText(i == -1 ? TypeFormatsDialog::tr("Reset") : typeFormats.at(i));
|
choice->setText(i == -1 ? TypeFormatsDialog::tr("Reset")
|
||||||
|
: WatchHandler::nameForFormat(typeFormats.at(i)));
|
||||||
m_layout->addWidget(choice, row, column++);
|
m_layout->addWidget(choice, row, column++);
|
||||||
if (i == current)
|
if (i == current)
|
||||||
choice->setChecked(true);
|
choice->setChecked(true);
|
||||||
@@ -868,7 +869,6 @@ private:
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
TypeFormatsDialog::TypeFormatsDialog(QWidget *parent)
|
TypeFormatsDialog::TypeFormatsDialog(QWidget *parent)
|
||||||
: QDialog(parent), m_ui(new TypeFormatsDialogUi(this))
|
: QDialog(parent), m_ui(new TypeFormatsDialogUi(this))
|
||||||
{
|
{
|
||||||
@@ -888,7 +888,7 @@ TypeFormatsDialog::~TypeFormatsDialog()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TypeFormatsDialog::addTypeFormats(const QString &type0,
|
void TypeFormatsDialog::addTypeFormats(const QString &type0,
|
||||||
const QStringList &typeFormats, int current)
|
const DisplayFormats &typeFormats, int current)
|
||||||
{
|
{
|
||||||
QString type = type0;
|
QString type = type0;
|
||||||
type.replace(QLatin1String("__"), QLatin1String("::"));
|
type.replace(QLatin1String("__"), QLatin1String("::"));
|
||||||
@@ -900,10 +900,5 @@ void TypeFormatsDialog::addTypeFormats(const QString &type0,
|
|||||||
m_ui->pages[pos]->addTypeFormats(type, typeFormats, current);
|
m_ui->pages[pos]->addTypeFormats(type, typeFormats, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
DumperTypeFormats TypeFormatsDialog::typeFormats() const
|
|
||||||
{
|
|
||||||
return DumperTypeFormats();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -31,6 +31,8 @@
|
|||||||
#ifndef DEBUGGER_DIALOGS_H
|
#ifndef DEBUGGER_DIALOGS_H
|
||||||
#define DEBUGGER_DIALOGS_H
|
#define DEBUGGER_DIALOGS_H
|
||||||
|
|
||||||
|
#include "watchhandler.h"
|
||||||
|
|
||||||
#include <projectexplorer/kitchooser.h>
|
#include <projectexplorer/kitchooser.h>
|
||||||
#include <projectexplorer/abi.h>
|
#include <projectexplorer/abi.h>
|
||||||
|
|
||||||
@@ -162,8 +164,6 @@ private:
|
|||||||
QDialogButtonBox *m_box;
|
QDialogButtonBox *m_box;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QHash<QString, QStringList> DumperTypeFormats;
|
|
||||||
|
|
||||||
class StartRemoteEngineDialog : public QDialog
|
class StartRemoteEngineDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -191,9 +191,8 @@ public:
|
|||||||
explicit TypeFormatsDialog(QWidget *parent);
|
explicit TypeFormatsDialog(QWidget *parent);
|
||||||
~TypeFormatsDialog();
|
~TypeFormatsDialog();
|
||||||
|
|
||||||
void addTypeFormats(const QString &type, const QStringList &formats,
|
void addTypeFormats(const QString &type, const DisplayFormats &formats,
|
||||||
int currentFormat);
|
int currentFormat);
|
||||||
DumperTypeFormats typeFormats() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TypeFormatsDialogUi *m_ui;
|
TypeFormatsDialogUi *m_ui;
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#include "simplifytype.h"
|
#include "simplifytype.h"
|
||||||
#include "imageviewer.h"
|
#include "imageviewer.h"
|
||||||
#include "watchutils.h"
|
#include "watchutils.h"
|
||||||
|
#include "cdb/cdbengine.h" // Remove after string freeze
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
@@ -239,7 +240,7 @@ public:
|
|||||||
QSet<QByteArray> m_expandedINames;
|
QSet<QByteArray> m_expandedINames;
|
||||||
QTimer m_requestUpdateTimer;
|
QTimer m_requestUpdateTimer;
|
||||||
|
|
||||||
DumperTypeFormats m_reportedTypeFormats;
|
QHash<QString, DisplayFormats> m_reportedTypeFormats; // Type name -> Dumper Formats
|
||||||
QHash<QByteArray, QString> m_valueCache;
|
QHash<QByteArray, QString> m_valueCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -943,22 +944,31 @@ static inline QString msgArrayFormat(int n)
|
|||||||
QString WatchModel::nameForFormat(int format)
|
QString WatchModel::nameForFormat(int format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
case AutomaticFormat: return QLatin1String("");
|
||||||
|
|
||||||
case RawFormat: return tr("Raw Data");
|
case RawFormat: return tr("Raw Data");
|
||||||
|
case SimpleFormat: return CdbEngine::tr("Normal"); // FIXME: String
|
||||||
|
case EnhancedFormat: return QLatin1String("Enhanced"); // FIXME: String
|
||||||
|
case SeparateFormat: return CdbEngine::tr("Separate Window"); // FIXME: String
|
||||||
|
|
||||||
case Latin1StringFormat: return tr("Latin1 String");
|
case Latin1StringFormat: return tr("Latin1 String");
|
||||||
|
case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window");
|
||||||
case Utf8StringFormat: return tr("UTF-8 String");
|
case Utf8StringFormat: return tr("UTF-8 String");
|
||||||
|
case SeparateUtf8StringFormat: return tr("UTF-8 String in Separate Window");
|
||||||
case Local8BitStringFormat: return tr("Local 8-Bit String");
|
case Local8BitStringFormat: return tr("Local 8-Bit String");
|
||||||
case Utf16StringFormat: return tr("UTF-16 String");
|
case Utf16StringFormat: return tr("UTF-16 String");
|
||||||
case Ucs4StringFormat: return tr("UCS-4 String");
|
case Ucs4StringFormat: return tr("UCS-4 String");
|
||||||
|
|
||||||
case Array10Format: return msgArrayFormat(10);
|
case Array10Format: return msgArrayFormat(10);
|
||||||
case Array100Format: return msgArrayFormat(100);
|
case Array100Format: return msgArrayFormat(100);
|
||||||
case Array1000Format: return msgArrayFormat(1000);
|
case Array1000Format: return msgArrayFormat(1000);
|
||||||
case Array10000Format: return msgArrayFormat(10000);
|
case Array10000Format: return msgArrayFormat(10000);
|
||||||
case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window");
|
|
||||||
case SeparateUtf8StringFormat: return tr("UTF-8 String in Separate Window");
|
|
||||||
case DecimalIntegerFormat: return tr("Decimal Integer");
|
case DecimalIntegerFormat: return tr("Decimal Integer");
|
||||||
case HexadecimalIntegerFormat: return tr("Hexadecimal Integer");
|
case HexadecimalIntegerFormat: return tr("Hexadecimal Integer");
|
||||||
case BinaryIntegerFormat: return tr("Binary Integer");
|
case BinaryIntegerFormat: return tr("Binary Integer");
|
||||||
case OctalIntegerFormat: return tr("Octal Integer");
|
case OctalIntegerFormat: return tr("Octal Integer");
|
||||||
|
|
||||||
case CompactFloatFormat: return tr("Compact Float");
|
case CompactFloatFormat: return tr("Compact Float");
|
||||||
case ScientificFloatFormat: return tr("Scientific Float");
|
case ScientificFloatFormat: return tr("Scientific Float");
|
||||||
}
|
}
|
||||||
@@ -967,9 +977,9 @@ QString WatchModel::nameForFormat(int format)
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeFormatList WatchItem::typeFormatList() const
|
DisplayFormats WatchItem::typeFormatList() const
|
||||||
{
|
{
|
||||||
TypeFormatList formats;
|
DisplayFormats formats;
|
||||||
|
|
||||||
// Types supported by dumpers:
|
// Types supported by dumpers:
|
||||||
// Hack: Compensate for namespaces.
|
// Hack: Compensate for namespaces.
|
||||||
@@ -981,9 +991,7 @@ TypeFormatList WatchItem::typeFormatList() const
|
|||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
t.truncate(pos);
|
t.truncate(pos);
|
||||||
t.replace(QLatin1Char(':'), QLatin1Char('_'));
|
t.replace(QLatin1Char(':'), QLatin1Char('_'));
|
||||||
QStringList reported = watchModel()->m_reportedTypeFormats.value(t);
|
formats << watchModel()->m_reportedTypeFormats.value(t);
|
||||||
for (int i = 0, n = reported.size(); i != n; ++i)
|
|
||||||
formats.append(TypeFormatItem(reported.at(i), i));
|
|
||||||
|
|
||||||
// Fixed artificial string and pointer types.
|
// Fixed artificial string and pointer types.
|
||||||
if (origaddr || isPointerType(type)) {
|
if (origaddr || isPointerType(type)) {
|
||||||
@@ -1531,6 +1539,11 @@ int WatchHandler::format(const QByteArray &iname) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString WatchHandler::nameForFormat(int format)
|
||||||
|
{
|
||||||
|
return WatchModel::nameForFormat(format);
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray WatchHandler::typeFormatRequests() const
|
QByteArray WatchHandler::typeFormatRequests() const
|
||||||
{
|
{
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
@@ -1539,7 +1552,7 @@ QByteArray WatchHandler::typeFormatRequests() const
|
|||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
const int format = it.value();
|
const int format = it.value();
|
||||||
if (format >= RawFormat && format < ArtificialFormatBase) {
|
if (format != AutomaticFormat) {
|
||||||
ba.append(it.key().toHex());
|
ba.append(it.key().toHex());
|
||||||
ba.append('=');
|
ba.append('=');
|
||||||
ba.append(QByteArray::number(format));
|
ba.append(QByteArray::number(format));
|
||||||
@@ -1559,7 +1572,7 @@ QByteArray WatchHandler::individualFormatRequests() const
|
|||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
const int format = it.value();
|
const int format = it.value();
|
||||||
if (format >= RawFormat && format < ArtificialFormatBase) {
|
if (format != AutomaticFormat) {
|
||||||
ba.append(it.key());
|
ba.append(it.key());
|
||||||
ba.append('=');
|
ba.append('=');
|
||||||
ba.append(QByteArray::number(it.value()));
|
ba.append(QByteArray::number(it.value()));
|
||||||
@@ -1588,7 +1601,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
|
|||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
const int format = it.value();
|
const int format = it.value();
|
||||||
if (format >= RawFormat && format < ArtificialFormatBase)
|
if (format != AutomaticFormat)
|
||||||
cmd->arg(it.key(), format);
|
cmd->arg(it.key(), format);
|
||||||
}
|
}
|
||||||
cmd->endGroup();
|
cmd->endGroup();
|
||||||
@@ -1598,7 +1611,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
|
|||||||
while (it2.hasNext()) {
|
while (it2.hasNext()) {
|
||||||
it2.next();
|
it2.next();
|
||||||
const int format = it2.value();
|
const int format = it2.value();
|
||||||
if (format >= RawFormat && format < ArtificialFormatBase)
|
if (format != AutomaticFormat)
|
||||||
cmd->arg(it2.key(), format);
|
cmd->arg(it2.key(), format);
|
||||||
}
|
}
|
||||||
cmd->endGroup();
|
cmd->endGroup();
|
||||||
@@ -1607,20 +1620,18 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
|
|||||||
void WatchHandler::addDumpers(const GdbMi &dumpers)
|
void WatchHandler::addDumpers(const GdbMi &dumpers)
|
||||||
{
|
{
|
||||||
foreach (const GdbMi &dumper, dumpers.children()) {
|
foreach (const GdbMi &dumper, dumpers.children()) {
|
||||||
QStringList formats(tr("Raw structure"));
|
DisplayFormats formats;
|
||||||
foreach (const QByteArray &format, dumper["formats"].data().split(',')) {
|
formats.append(RawFormat);
|
||||||
if (format == "Normal")
|
QByteArray reportedFormats = dumper["formats"].data();
|
||||||
formats.append(tr("Normal"));
|
foreach (const QByteArray &format, reportedFormats.split(',')) {
|
||||||
else if (format == "Displayed")
|
if (int f = format.toInt())
|
||||||
formats.append(tr("Displayed"));
|
formats.append(DisplayFormat(f));
|
||||||
else if (!format.isEmpty())
|
|
||||||
formats.append(QString::fromLatin1(format));
|
|
||||||
}
|
}
|
||||||
addTypeFormats(dumper["type"].data(), formats);
|
addTypeFormats(dumper["type"].data(), formats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &formats)
|
void WatchHandler::addTypeFormats(const QByteArray &type, const DisplayFormats &formats)
|
||||||
{
|
{
|
||||||
m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats);
|
m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats);
|
||||||
}
|
}
|
||||||
@@ -1643,16 +1654,6 @@ QString WatchHandler::editorContents()
|
|||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchHandler::setTypeFormats(const DumperTypeFormats &typeFormats)
|
|
||||||
{
|
|
||||||
m_model->m_reportedTypeFormats = typeFormats;
|
|
||||||
}
|
|
||||||
|
|
||||||
DumperTypeFormats WatchHandler::typeFormats() const
|
|
||||||
{
|
|
||||||
return m_model->m_reportedTypeFormats;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WatchHandler::scheduleResetLocation()
|
void WatchHandler::scheduleResetLocation()
|
||||||
{
|
{
|
||||||
m_model->m_contentsValid = false;
|
m_model->m_contentsValid = false;
|
||||||
@@ -1698,30 +1699,6 @@ QSet<QByteArray> WatchHandler::expandedINames() const
|
|||||||
return m_model->m_expandedINames;
|
return m_model->m_expandedINames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TypeFormatItem/List
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypeFormatItem::TypeFormatItem(const QString &display, int format)
|
|
||||||
: display(display), format(format)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void TypeFormatList::append(int format)
|
|
||||||
{
|
|
||||||
append(TypeFormatItem(WatchModel::nameForFormat(format), format));
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeFormatItem TypeFormatList::find(int format) const
|
|
||||||
{
|
|
||||||
for (int i = 0; i != size(); ++i)
|
|
||||||
if (at(i).format == format)
|
|
||||||
return at(i);
|
|
||||||
return TypeFormatItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// WatchItem
|
// WatchItem
|
||||||
|
@@ -44,23 +44,48 @@ class DebuggerCommand;
|
|||||||
class DebuggerEngine;
|
class DebuggerEngine;
|
||||||
class WatchModel;
|
class WatchModel;
|
||||||
|
|
||||||
class TypeFormatItem
|
// Special formats. Keep in sync with dumper.py.
|
||||||
|
enum DisplayFormat
|
||||||
{
|
{
|
||||||
public:
|
AutomaticFormat, // Based on type for individuals, dumper default for types.
|
||||||
TypeFormatItem() : format(-1) {}
|
RawFormat,
|
||||||
TypeFormatItem(const QString &display, int format);
|
|
||||||
|
|
||||||
QString display;
|
SimpleFormat, // Typical simple format (e.g. for QModelIndex row/column)
|
||||||
int format;
|
EnhancedFormat, // Enhanced format (e.g. for QModelIndex with resolved display)
|
||||||
|
SeparateFormat, // Display in separate Window
|
||||||
|
|
||||||
|
Latin1StringFormat,
|
||||||
|
SeparateLatin1StringFormat,
|
||||||
|
Utf8StringFormat,
|
||||||
|
SeparateUtf8StringFormat,
|
||||||
|
Local8BitStringFormat,
|
||||||
|
Utf16StringFormat,
|
||||||
|
Ucs4StringFormat,
|
||||||
|
|
||||||
|
Array10Format,
|
||||||
|
Array100Format,
|
||||||
|
Array1000Format,
|
||||||
|
Array10000Format,
|
||||||
|
ArrayPlotFormat,
|
||||||
|
|
||||||
|
CompactMapFormat,
|
||||||
|
DirectQListStorageFormat,
|
||||||
|
IndirectQListStorageFormat,
|
||||||
|
|
||||||
|
// Not used in *.py.
|
||||||
|
BoolTextFormat,
|
||||||
|
BoolIntegerFormat,
|
||||||
|
|
||||||
|
DecimalIntegerFormat,
|
||||||
|
HexadecimalIntegerFormat,
|
||||||
|
BinaryIntegerFormat,
|
||||||
|
OctalIntegerFormat,
|
||||||
|
|
||||||
|
CompactFloatFormat,
|
||||||
|
ScientificFloatFormat,
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeFormatList : public QVector<TypeFormatItem>
|
typedef QVector<DisplayFormat> DisplayFormats;
|
||||||
{
|
|
||||||
public:
|
|
||||||
using QVector::append;
|
|
||||||
void append(int format);
|
|
||||||
TypeFormatItem find(int format) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WatchItem : public Utils::TreeItem, public WatchData
|
class WatchItem : public Utils::TreeItem, public WatchData
|
||||||
{
|
{
|
||||||
@@ -91,7 +116,7 @@ private:
|
|||||||
WatchItem *parentItem() const;
|
WatchItem *parentItem() const;
|
||||||
const WatchModel *watchModel() const;
|
const WatchModel *watchModel() const;
|
||||||
WatchModel *watchModel();
|
WatchModel *watchModel();
|
||||||
TypeFormatList typeFormatList() const;
|
DisplayFormats typeFormatList() const;
|
||||||
|
|
||||||
bool canFetchMore() const;
|
bool canFetchMore() const;
|
||||||
QVariant data(int column, int role) const;
|
QVariant data(int column, int role) const;
|
||||||
@@ -101,46 +126,6 @@ private:
|
|||||||
bool fetchTriggered;
|
bool fetchTriggered;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special formats. Keep in sync with dumper.py.
|
|
||||||
enum DisplayFormat
|
|
||||||
{
|
|
||||||
AutomaticFormat = -1, // Based on type for individuals, dumper default for types.
|
|
||||||
RawFormat = 0,
|
|
||||||
|
|
||||||
// Values between 1 and 99 refer to dumper provided custom formats.
|
|
||||||
|
|
||||||
// Values between 100 and 199 refer to well-known formats handled in dumpers.
|
|
||||||
KnownDumperFormatBase = 100,
|
|
||||||
Latin1StringFormat,
|
|
||||||
Utf8StringFormat,
|
|
||||||
Local8BitStringFormat,
|
|
||||||
Utf16StringFormat,
|
|
||||||
Ucs4StringFormat,
|
|
||||||
|
|
||||||
Array10Format,
|
|
||||||
Array100Format,
|
|
||||||
Array1000Format,
|
|
||||||
Array10000Format,
|
|
||||||
|
|
||||||
SeparateLatin1StringFormat,
|
|
||||||
SeparateUtf8StringFormat,
|
|
||||||
|
|
||||||
|
|
||||||
// Values above 200 refer to format solely handled in the WatchHandler code
|
|
||||||
ArtificialFormatBase = 200,
|
|
||||||
|
|
||||||
BoolTextFormat,
|
|
||||||
BoolIntegerFormat,
|
|
||||||
|
|
||||||
DecimalIntegerFormat,
|
|
||||||
HexadecimalIntegerFormat,
|
|
||||||
BinaryIntegerFormat,
|
|
||||||
OctalIntegerFormat,
|
|
||||||
|
|
||||||
CompactFloatFormat,
|
|
||||||
ScientificFloatFormat,
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateParameters
|
class UpdateParameters
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -150,8 +135,6 @@ public:
|
|||||||
QByteArray varList;
|
QByteArray varList;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QHash<QString, QStringList> DumperTypeFormats; // Type name -> Dumper Formats
|
|
||||||
|
|
||||||
class WatchModelBase : public Utils::TreeModel
|
class WatchModelBase : public Utils::TreeModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -201,11 +184,10 @@ public:
|
|||||||
QByteArray individualFormatRequests() const;
|
QByteArray individualFormatRequests() const;
|
||||||
|
|
||||||
int format(const QByteArray &iname) const;
|
int format(const QByteArray &iname) const;
|
||||||
|
static QString nameForFormat(int format);
|
||||||
|
|
||||||
void addDumpers(const GdbMi &dumpers);
|
void addDumpers(const GdbMi &dumpers);
|
||||||
void addTypeFormats(const QByteArray &type, const QStringList &formats);
|
void addTypeFormats(const QByteArray &type, const DisplayFormats &formats);
|
||||||
void setTypeFormats(const DumperTypeFormats &typeFormats);
|
|
||||||
DumperTypeFormats typeFormats() const;
|
|
||||||
|
|
||||||
void setUnprintableBase(int base);
|
void setUnprintableBase(int base);
|
||||||
static int unprintableBase();
|
static int unprintableBase();
|
||||||
@@ -237,6 +219,6 @@ private:
|
|||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
|
Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
|
||||||
Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList)
|
Q_DECLARE_METATYPE(Debugger::Internal::DisplayFormats)
|
||||||
|
|
||||||
#endif // DEBUGGER_WATCHHANDLER_H
|
#endif // DEBUGGER_WATCHHANDLER_H
|
||||||
|
@@ -554,12 +554,10 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
|
|||||||
const QModelIndex mi2 = mi.sibling(mi.row(), 2);
|
const QModelIndex mi2 = mi.sibling(mi.row(), 2);
|
||||||
const QString type = mi2.data().toString();
|
const QString type = mi2.data().toString();
|
||||||
|
|
||||||
const TypeFormatList alternativeFormats =
|
const DisplayFormats alternativeFormats =
|
||||||
mi.data(LocalsTypeFormatListRole).value<TypeFormatList>();
|
mi.data(LocalsTypeFormatListRole).value<DisplayFormats>();
|
||||||
int typeFormat =
|
const int typeFormat = mi.data(LocalsTypeFormatRole).toInt();
|
||||||
mi.data(LocalsTypeFormatRole).toInt();
|
const int individualFormat = mi.data(LocalsIndividualFormatRole).toInt();
|
||||||
const int individualFormat =
|
|
||||||
mi.data(LocalsIndividualFormatRole).toInt();
|
|
||||||
const int unprintableBase = WatchHandler::unprintableBase();
|
const int unprintableBase = WatchHandler::unprintableBase();
|
||||||
|
|
||||||
QAction *showUnprintableUnicode = 0;
|
QAction *showUnprintableUnicode = 0;
|
||||||
@@ -595,7 +593,7 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
|
|||||||
dummy->setEnabled(false);
|
dummy->setEnabled(false);
|
||||||
QString msg = (individualFormat == AutomaticFormat && typeFormat != AutomaticFormat)
|
QString msg = (individualFormat == AutomaticFormat && typeFormat != AutomaticFormat)
|
||||||
? tr("Use Format for Type (Currently %1)")
|
? tr("Use Format for Type (Currently %1)")
|
||||||
.arg(alternativeFormats.find(typeFormat).display)
|
.arg(WatchHandler::nameForFormat(typeFormat))
|
||||||
: tr("Use Display Format Based on Type") + QLatin1Char(' ');
|
: tr("Use Display Format Based on Type") + QLatin1Char(' ');
|
||||||
|
|
||||||
QAction *clearIndividualFormatAction = formatMenu->addAction(spacer + msg);
|
QAction *clearIndividualFormatAction = formatMenu->addAction(spacer + msg);
|
||||||
@@ -608,8 +606,8 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (int i = 0; i != alternativeFormats.size(); ++i) {
|
for (int i = 0; i != alternativeFormats.size(); ++i) {
|
||||||
const QString display = spacer + alternativeFormats.at(i).display;
|
const int format = alternativeFormats.at(i);
|
||||||
const int format = alternativeFormats.at(i).format;
|
const QString display = spacer + WatchHandler::nameForFormat(format);
|
||||||
QAction *act = new QAction(display, formatMenu);
|
QAction *act = new QAction(display, formatMenu);
|
||||||
act->setCheckable(true);
|
act->setCheckable(true);
|
||||||
act->setChecked(format == individualFormat);
|
act->setChecked(format == individualFormat);
|
||||||
@@ -633,9 +631,9 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (int i = 0; i != alternativeFormats.size(); ++i) {
|
for (int i = 0; i != alternativeFormats.size(); ++i) {
|
||||||
const QString display = spacer + alternativeFormats.at(i).display;
|
const int format = alternativeFormats.at(i);
|
||||||
|
const QString display = spacer + WatchHandler::nameForFormat(format);
|
||||||
QAction *act = new QAction(display, formatMenu);
|
QAction *act = new QAction(display, formatMenu);
|
||||||
const int format = alternativeFormats.at(i).format;
|
|
||||||
act->setCheckable(true);
|
act->setCheckable(true);
|
||||||
act->setChecked(format == typeFormat);
|
act->setChecked(format == typeFormat);
|
||||||
formatMenu->addAction(act);
|
formatMenu->addAction(act);
|
||||||
|
Reference in New Issue
Block a user