summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjk <hjk@theqtcompany.com>2015-03-20 16:03:59 +0100
committerhjk <hjk@theqtcompany.com>2015-03-23 14:12:43 +0000
commit48ac7c186b0228f13bbd8a0f00ab39300765dc4a (patch)
tree73c36fc0dee1f7e922473f71b3ac8418dece7bb1
parentb727c15a534ce337e8cfcd49a0b091aee5462bf3 (diff)
downloadqt-creator-48ac7c186b0228f13bbd8a0f00ab39300765dc4a.tar.gz
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>
-rw-r--r--share/qtcreator/debugger/dumper.py148
-rw-r--r--share/qtcreator/debugger/gdbbridge.py31
-rw-r--r--share/qtcreator/debugger/lldbbridge.py11
-rw-r--r--share/qtcreator/debugger/qttypes.py59
-rw-r--r--share/qtcreator/debugger/stdtypes.py5
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp14
-rw-r--r--src/plugins/debugger/debuggerdialogs.cpp13
-rw-r--r--src/plugins/debugger/debuggerdialogs.h7
-rw-r--r--src/plugins/debugger/watchhandler.cpp87
-rw-r--r--src/plugins/debugger/watchhandler.h102
-rw-r--r--src/plugins/debugger/watchwindow.cpp20
11 files changed, 221 insertions, 276 deletions
diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index 6fa45a43c7..52e475e27f 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -67,9 +67,15 @@ StartRemoteProcess, \
# Known special formats. Keep in sync with DisplayFormat in watchhandler.h
-KnownDumperFormatBase, \
+AutomaticFormat, \
+RawFormat, \
+SimpleFormat, \
+EnhancedFormat, \
+SeparateFormat, \
Latin1StringFormat, \
+SeparateLatin1StringFormat, \
Utf8StringFormat, \
+SeparateUtf8StringFormat, \
Local8BitStringFormat, \
Utf16StringFormat, \
Ucs4StringFormat, \
@@ -77,9 +83,11 @@ Array10Format, \
Array100Format, \
Array1000Format, \
Array10000Format, \
-SeparateLatin1StringFormat, \
-SeparateUtf8StringFormat \
- = range(100, 112)
+ArrayPlotFormat, \
+CompactMapFormat, \
+DirectQListStorageFormat, \
+IndirectQListStorageFormat, \
+ = range(0, 20)
# Breakpoints. Keep synchronized with BreakpointType in breakpoint.h
UnknownType, \
@@ -171,10 +179,10 @@ if hasSubprocess and hasPlot:
def arrayForms():
global hasPlot
- return "Normal,Plot" if hasPlot else "Normal"
+ return [ArrayPlotFormat] if hasPlot else []
def mapForms():
- return "Normal,Compact"
+ return [CompactMapFormat]
class ReportItem:
@@ -583,12 +591,13 @@ class DumperBase:
elided, shown = self.computeLimit(size, limit)
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
elided, shown = self.computeLimit(bytelen, self.displayStringLimit)
mem = self.readMemory(data, shown)
if charSize == 1:
- if format == 1 or format == 2:
+ if displayFormat == Latin1StringFormat \
+ or displayFormat == SeparateLatin1StringFormat:
encodingType = Hex2EncodedLatin1
else:
encodingType = Hex2EncodedUtf8
@@ -603,9 +612,11 @@ class DumperBase:
self.putNumChild(0)
self.putValue(mem, encodingType, elided=elided)
- if format == 1 or format == 3:
+ if displayFormat == Latin1StringFormat \
+ or displayFormat == Utf8StringFormat:
self.putDisplay(StopDisplay)
- elif format == 2 or format == 4:
+ elif displayFormat == SeparateLatin1StringFormat \
+ or displayFormat == SeparateUtf8StringFormat:
self.putField("editformat", displayType)
elided, shown = self.computeLimit(bytelen, 100000)
self.putField("editvalue", self.readMemory(data, shown))
@@ -801,9 +812,8 @@ class DumperBase:
self.putFields(value, dumpBase)
def isMapCompact(self, keyType, valueType):
- format = self.currentItemFormat()
- if format == 2:
- return True # Compact.
+ if self.currentItemFormat() == CompactMapFormat:
+ return True
return self.isSimpleType(keyType) and self.isSimpleType(valueType)
@@ -920,13 +930,13 @@ class DumperBase:
except:
p = None
- itemFormat = self.currentItemFormat()
+ displayFormat = self.currentItemFormat()
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)
pass
- elif itemFormat is None:
+ elif displayFormat is None:
innerTypeName = str(innerType.unqualified())
blob = self.readMemory(self.addressOf(value), arrayType.sizeof)
if innerTypeName == "char":
@@ -969,6 +979,31 @@ class DumperBase:
pass
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):
enc = self.simpleEncoding(innerType)
if not enc:
@@ -991,8 +1026,8 @@ class DumperBase:
data = self.readMemory(base, shown)
self.putValue(data, Hex2EncodedLatin1, elided=elided)
- def putDisplay(self, format, value = None, cmd = None):
- self.put('editformat="%s",' % format)
+ def putDisplay(self, editFormat, value = None, cmd = None):
+ self.put('editformat="%s",' % editFormat)
if cmd is None:
if not value is None:
self.put('editvalue="%s",' % value)
@@ -1000,8 +1035,8 @@ class DumperBase:
self.put('editvalue="%s|%s",' % (cmd, value))
# This is shared by pointer and array formatting.
- def tryPutSimpleFormattedPointer(self, value, typeName, itemFormat, limit):
- if itemFormat == None and typeName == "char":
+ def tryPutSimpleFormattedPointer(self, value, typeName, displayFormat, limit):
+ if displayFormat == AutomaticFormat and typeName == "char":
# Use Latin1 as default for char *.
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
@@ -1009,56 +1044,49 @@ class DumperBase:
self.putDisplay(StopDisplay)
return True
- if itemFormat == Latin1StringFormat:
- # Explicitly requested Latin1 formatting.
+ if displayFormat == Latin1StringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedLatin1, elided=elided)
self.putDisplay(StopDisplay)
return True
- if itemFormat == SeparateLatin1StringFormat:
- # Explicitly requested Latin1 formatting in separate window.
+ if displayFormat == SeparateLatin1StringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedLatin1, elided=elided)
self.putDisplay(DisplayLatin1String, data)
return True
- if itemFormat == Utf8StringFormat:
- # Explicitly requested UTF-8 formatting.
+ if displayFormat == Utf8StringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedUtf8, elided=elided)
self.putDisplay(StopDisplay)
return True
- if itemFormat == SeparateUtf8StringFormat:
- # Explicitly requested UTF-8 formatting in separate window.
+ if displayFormat == SeparateUtf8StringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedUtf8, elided=elided)
self.putDisplay(DisplayUtf8String, data)
return True
- if itemFormat == Local8BitStringFormat:
- # Explicitly requested local 8 bit formatting.
+ if displayFormat == Local8BitStringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 1, limit)
self.putValue(data, Hex2EncodedLocal8Bit, elided=elided)
self.putDisplay(StopDisplay)
return True
- if itemFormat == Utf16StringFormat:
- # Explicitly requested UTF-16 formatting.
+ if displayFormat == Utf16StringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 2, limit)
self.putValue(data, Hex4EncodedLittleEndian, elided=elided)
self.putDisplay(StopDisplay)
return True
- if itemFormat == Ucs4StringFormat:
- # Explicitly requested UCS-4 formatting.
+ if displayFormat == Ucs4StringFormat:
self.putType(typeName)
(elided, data) = self.encodeCArray(value, 4, limit)
self.putValue(data, Hex8EncodedLittleEndian, elided=elided)
@@ -1091,16 +1119,16 @@ class DumperBase:
self.putNumChild(0)
return
- format = self.currentItemFormat(value.type)
+ displayFormat = self.currentItemFormat(value.type)
if innerTypeName == "void":
- #warn("VOID POINTER: %s" % format)
+ #warn("VOID POINTER: %s" % displayFormat)
self.putType(typeName)
self.putValue(str(value))
self.putNumChild(0)
return
- if format == 0:
+ if displayFormat == RawFormat:
# Explicitly requested bald pointer.
self.putType(typeName)
self.putValue(self.hexencode(str(value)), Hex2EncodedUtf8WithoutQuotes)
@@ -1112,16 +1140,15 @@ class DumperBase:
return
limit = self.displayStringLimit
- if format == DisplayLatin1String or format == DisplayUtf8String:
+ if displayFormat == SeparateLatin1StringFormat \
+ or displayFormat == SeparateUtf8StringFormat:
limit = 1000000
- if self.tryPutSimpleFormattedPointer(value, typeName, format, limit):
+ if self.tryPutSimpleFormattedPointer(value, typeName, displayFormat, limit):
self.putNumChild(0)
return
- if not format is None \
- and format >= Array10Format and format <= Array1000Format:
- # Explicitly requested formatting as array of n items.
- n = (10, 100, 1000, 10000)[format - Array10Format]
+ if Array10Format <= displayFormat and displayFormat <= Array1000Format:
+ n = (10, 100, 1000, 10000)[displayFormat - Array10Format]
self.putType(typeName)
self.putItemCount(n)
self.putArrayData(value, n, innerType)
@@ -1141,9 +1168,7 @@ class DumperBase:
#warn("AUTODEREF: %s" % self.autoDerefPointers)
#warn("INAME: %s" % self.currentIName)
if self.autoDerefPointers or self.currentIName.endswith('.this'):
- ## Generic pointer type with format None
- #warn("GENERIC AUTODEREF POINTER: %s AT %s TO %s"
- # % (type, value.address, innerTypeName))
+ # Generic pointer type with AutomaticFormat.
# Never dereference char types.
if innerTypeName != "char" \
and innerTypeName != "signed char" \
@@ -1491,13 +1516,13 @@ class DumperBase:
return typeName == "QStringList" and self.qtVersion() >= 0x050000
def currentItemFormat(self, type = None):
- format = self.formats.get(self.currentIName)
- if format is None:
+ displayFormat = self.formats.get(self.currentIName, AutomaticFormat)
+ if displayFormat == AutomaticFormat:
if type is None:
type = self.currentType.value
needle = self.stripForFormat(str(type))
- format = self.typeformats.get(needle)
- return format
+ displayFormat = self.typeformats.get(needle, AutomaticFormat)
+ return displayFormat
def putArrayData(self, base, n, innerType = None,
childNumChild = None, maxNumChild = 10000):
@@ -1511,19 +1536,19 @@ class DumperBase:
i = toInteger(i)
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):
self.putEmptyValue()
self.putType("%s [%d]" % (typeName, n))
self.putArrayData(addr, n, self.lookupType(typeName))
self.putAddress(addr)
- def putPlotData(self, base, n, typeobj, plotFormat = 2):
+ def putPlotData(self, base, n, typeobj):
if self.isExpanded():
self.putArrayData(base, n, typeobj)
if hasPlot:
if self.isSimpleType(typeobj):
- show = self.currentItemFormat() == plotFormat
+ show = self.currentItemFormat() == ArrayPlotFormat
iname = self.currentIName
data = []
if show:
@@ -1688,15 +1713,13 @@ class DumperBase:
if funcname.startswith("qdump__"):
typename = funcname[7:]
self.qqDumpers[typename] = function
- self.qqFormats[typename] = self.qqFormats.get(typename, "")
+ self.qqFormats[typename] = self.qqFormats.get(typename, [])
elif funcname.startswith("qform__"):
typename = funcname[7:]
- formats = ""
try:
- formats = function()
+ self.qqFormats[typename] = function()
except:
- pass
- self.qqFormats[typename] = formats
+ self.qqFormats[typename] = []
elif funcname.startswith("qedit__"):
typename = funcname[7:]
try:
@@ -1721,15 +1744,14 @@ class DumperBase:
msg = "dumpers=["
for key, value in self.qqFormats.items():
- if key in self.qqEditable:
- msg += '{type="%s",formats="%s",editable="true"},' % (key, value)
- else:
- msg += '{type="%s",formats="%s"},' % (key, value)
+ editable = ',editable="true"' if key in self.qqEditable else ''
+ formats = (',formats=\"%s\"' % str(value)[1:-1]) if len(value) else ''
+ msg += '{type="%s"%s%s},' % (key, editable, formats)
msg += ']'
self.reportDumpers(msg)
def reportDumpers(self, msg):
- raise NotImplementedError # Pure
+ raise NotImplementedError
def reloadDumpers(self, args):
for mod in self.dumpermodules:
diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py
index 089c4ae461..f22bd37b1d 100644
--- a/share/qtcreator/debugger/gdbbridge.py
+++ b/share/qtcreator/debugger/gdbbridge.py
@@ -1075,35 +1075,8 @@ class Dumper(DumperBase):
self.putItem(self.expensiveDowncast(value), False)
return
- format = self.currentItemFormat(typeName)
-
- 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
+ if self.tryPutPrettyItem(typeName, value):
+ return
# D arrays, gdc compiled.
if typeName.endswith("[]"):
diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py
index 4d81422388..fdf70468a8 100644
--- a/share/qtcreator/debugger/lldbbridge.py
+++ b/share/qtcreator/debugger/lldbbridge.py
@@ -1063,15 +1063,8 @@ class Dumper(DumperBase):
#warn("VALUE: %s" % value)
#warn("FANCY: %s" % self.useFancy)
- if self.useFancy:
- stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
- #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
+ if self.tryPutPrettyItem(typeName, value):
+ return
# Normal value
#numchild = 1 if value.MightHaveChildren() else 0
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index cff457ae44..f640786cef 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -53,24 +53,25 @@ def qdump__QAtomicPointer(d, value):
d.putSubItem("_q_value", q.dereference())
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):
data, size, alloc = d.byteArrayData(value)
d.putNumChild(size)
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
- format = d.currentItemFormat()
- if format == 1 or format is None:
+ displayFormat = d.currentItemFormat()
+ if displayFormat == AutomaticFormat or displayFormat == Latin1StringFormat:
d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedLatin1, elided=elided)
- elif format == 2:
+ elif displayFormat == SeparateLatin1StringFormat:
d.putValue(p, Hex2EncodedLatin1, elided=elided)
d.putField("editformat", DisplayLatin1String)
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
- elif format == 3:
+ elif displayFormat == Utf8StringFormat:
d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedUtf8, elided=elided)
- elif format == 4:
+ elif displayFormat == SeparateUtf8StringFormat:
d.putValue(p, Hex2EncodedUtf8, elided=elided)
d.putField("editformat", DisplayUtf8String)
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
@@ -92,14 +93,14 @@ def qdump__QChar(d, value):
def qform__QAbstractItemModel():
- return "Normal,Enhanced"
+ return [SimpleFormat, EnhancedFormat]
def qdump__QAbstractItemModel(d, value):
- format = d.currentItemFormat()
- if format == 1:
+ displayFormat = d.currentItemFormat()
+ if displayFormat == SimpleFormat:
d.putPlainChildren(value)
return
- #format == 2:
+ #displayFormat == EnhancedFormat:
# Create a default-constructed QModelIndex on the stack.
try:
ri = d.makeValue(d.qtNamespace() + "QModelIndex", "-1, -1, 0, 0")
@@ -134,11 +135,11 @@ def qdump__QAbstractItemModel(d, value):
#gdb.execute("call free($ri)")
def qform__QModelIndex():
- return "Normal,Enhanced"
+ return [SimpleFormat, EnhancedFormat]
def qdump__QModelIndex(d, value):
- format = d.currentItemFormat()
- if format == 1:
+ displayFormat = d.currentItemFormat()
+ if displayFormat == SimpleFormat:
d.putPlainChildren(value)
return
r = value["r"]
@@ -768,7 +769,7 @@ def qdump__QIPv6Address(d, value):
d.putPlainChildren(c)
def qform__QList():
- return "Assume Direct Storage,Assume Indirect Storage"
+ return [DirectQListStorageFormat, IndirectQListStorageFormat]
def qdump__QList(d, 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
# in the frontend.
# So as first approximation only do the 'isLarge' check:
- format = d.currentItemFormat()
- if format == 1:
+ displayFormat = d.currentItemFormat()
+ if displayFormat == DirectQListStorageFormat:
isInternal = True
- elif format == 2:
+ elif displayFormat == IndirectQListStorageFormat:
isInternal = False
else:
isInternal = innerSize <= stepSize and d.isMovableType(innerType)
@@ -818,7 +819,7 @@ def qdump__QList(d, value):
d.putSubItem(i, x)
def qform__QImage():
- return "Normal,Displayed"
+ return [SimpleFormat, SeparateFormat]
def qdump__QImage(d, value):
# This relies on current QImage layout:
@@ -861,10 +862,10 @@ def qdump__QImage(d, value):
d.putNumChild(0)
d.putType("void *")
- format = d.currentItemFormat()
- if format == 1:
+ displayFormat = d.currentItemFormat()
+ if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
- elif format == 2:
+ elif displayFormat == SeparateFormat:
# This is critical for performance. Writing to an external
# file using the following is faster when using GDB.
# 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])
def qform__QString():
- return "Inline,Separate Window"
+ return [SimpleFormat, SeparateFormat]
def qdump__QString(d, value):
d.putStringValue(value)
data, size, alloc = d.stringData(value)
d.putNumChild(size)
- format = d.currentItemFormat()
- if format == 1:
+ displayFormat = d.currentItemFormat()
+ if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
- elif format == 2:
+ elif displayFormat == SeparateFormat:
d.putField("editformat", DisplayUtf16String)
d.putField("editvalue", d.encodeString(value, limit=100000))
if d.isExpanded():
@@ -1847,7 +1848,7 @@ def qdump__QTextDocument(d, value):
def qform__QUrl():
- return "Inline,Separate Window"
+ return [SimpleFormat, SeparateFormat]
def qdump__QUrl(d, value):
if d.qtVersion() < 0x050000:
@@ -1911,10 +1912,10 @@ def qdump__QUrl(d, value):
url += path
d.putValue(url, Hex4EncodedLittleEndian)
- format = d.currentItemFormat()
- if format == 1:
+ displayFormat = d.currentItemFormat()
+ if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
- elif format == 2:
+ elif displayFormat == SeparateFormat:
d.putField("editformat", DisplayUtf16String)
d.putField("editvalue", url)
diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py
index 88e60f5228..54a6cc34d7 100644
--- a/share/qtcreator/debugger/stdtypes.py
+++ b/share/qtcreator/debugger/stdtypes.py
@@ -398,7 +398,8 @@ def qdump__std____debug__stack(d, value):
qdump__std__stack(d, value)
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):
qdump__std__stringHelper1(d, value, 1, d.currentItemFormat())
@@ -787,7 +788,7 @@ def qdump__string(d, value):
qdump__std__string(d, value)
def qform__std__wstring():
- return "Inline String,String in Separate Window"
+ return [SimpleFormat, SeparateFormat]
def qdump__std__wstring(d, value):
charSize = d.lookupType('wchar_t').sizeof
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 5522b7794b..c9c4920084 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -576,17 +576,21 @@ void CdbEngine::setupEngine()
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed")
notifyEngineSetupFailed();
}
- const QString normalFormat = tr("Normal");
- const QStringList stringFormats = QStringList()
- << normalFormat << tr("Separate Window");
+
+ DisplayFormats stringFormats;
+ stringFormats.append(SimpleFormat);
+ stringFormats.append(SeparateFormat);
+
WatchHandler *wh = watchHandler();
wh->addTypeFormats("QString", stringFormats);
wh->addTypeFormats("QString *", stringFormats);
wh->addTypeFormats("QByteArray", stringFormats);
wh->addTypeFormats("QByteArray *", stringFormats);
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);
}
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 7b724bad3d..066323c193 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -807,7 +807,7 @@ public:
}
void addTypeFormats(const QString &type,
- const QStringList &typeFormats, int current)
+ const DisplayFormats &typeFormats, int current)
{
const int row = m_layout->rowCount();
int column = 0;
@@ -815,7 +815,8 @@ public:
m_layout->addWidget(new QLabel(type), row, column++);
for (int i = -1; i != typeFormats.size(); ++i) {
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++);
if (i == current)
choice->setChecked(true);
@@ -868,7 +869,6 @@ private:
//
///////////////////////////////////////////////////////////////////////
-
TypeFormatsDialog::TypeFormatsDialog(QWidget *parent)
: QDialog(parent), m_ui(new TypeFormatsDialogUi(this))
{
@@ -888,7 +888,7 @@ TypeFormatsDialog::~TypeFormatsDialog()
}
void TypeFormatsDialog::addTypeFormats(const QString &type0,
- const QStringList &typeFormats, int current)
+ const DisplayFormats &typeFormats, int current)
{
QString type = type0;
type.replace(QLatin1String("__"), QLatin1String("::"));
@@ -900,10 +900,5 @@ void TypeFormatsDialog::addTypeFormats(const QString &type0,
m_ui->pages[pos]->addTypeFormats(type, typeFormats, current);
}
-DumperTypeFormats TypeFormatsDialog::typeFormats() const
-{
- return DumperTypeFormats();
-}
-
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index eee9ee11c4..9b0ddc4673 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -31,6 +31,8 @@
#ifndef DEBUGGER_DIALOGS_H
#define DEBUGGER_DIALOGS_H
+#include "watchhandler.h"
+
#include <projectexplorer/kitchooser.h>
#include <projectexplorer/abi.h>
@@ -162,8 +164,6 @@ private:
QDialogButtonBox *m_box;
};
-typedef QHash<QString, QStringList> DumperTypeFormats;
-
class StartRemoteEngineDialog : public QDialog
{
Q_OBJECT
@@ -191,9 +191,8 @@ public:
explicit TypeFormatsDialog(QWidget *parent);
~TypeFormatsDialog();
- void addTypeFormats(const QString &type, const QStringList &formats,
+ void addTypeFormats(const QString &type, const DisplayFormats &formats,
int currentFormat);
- DumperTypeFormats typeFormats() const;
private:
TypeFormatsDialogUi *m_ui;
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index a3177c30e9..cfcc0466c0 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -40,6 +40,7 @@
#include "simplifytype.h"
#include "imageviewer.h"
#include "watchutils.h"
+#include "cdb/cdbengine.h" // Remove after string freeze
#include <coreplugin/icore.h>
@@ -239,7 +240,7 @@ public:
QSet<QByteArray> m_expandedINames;
QTimer m_requestUpdateTimer;
- DumperTypeFormats m_reportedTypeFormats;
+ QHash<QString, DisplayFormats> m_reportedTypeFormats; // Type name -> Dumper Formats
QHash<QByteArray, QString> m_valueCache;
};
@@ -943,22 +944,31 @@ static inline QString msgArrayFormat(int n)
QString WatchModel::nameForFormat(int format)
{
switch (format) {
+ case AutomaticFormat: return QLatin1String("");
+
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 SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window");
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 Utf16StringFormat: return tr("UTF-16 String");
case Ucs4StringFormat: return tr("UCS-4 String");
+
case Array10Format: return msgArrayFormat(10);
case Array100Format: return msgArrayFormat(100);
case Array1000Format: return msgArrayFormat(1000);
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 HexadecimalIntegerFormat: return tr("Hexadecimal Integer");
case BinaryIntegerFormat: return tr("Binary Integer");
case OctalIntegerFormat: return tr("Octal Integer");
+
case CompactFloatFormat: return tr("Compact Float");
case ScientificFloatFormat: return tr("Scientific Float");
}
@@ -967,9 +977,9 @@ QString WatchModel::nameForFormat(int format)
return QString();
}
-TypeFormatList WatchItem::typeFormatList() const
+DisplayFormats WatchItem::typeFormatList() const
{
- TypeFormatList formats;
+ DisplayFormats formats;
// Types supported by dumpers:
// Hack: Compensate for namespaces.
@@ -981,9 +991,7 @@ TypeFormatList WatchItem::typeFormatList() const
if (pos >= 0)
t.truncate(pos);
t.replace(QLatin1Char(':'), QLatin1Char('_'));
- QStringList reported = watchModel()->m_reportedTypeFormats.value(t);
- for (int i = 0, n = reported.size(); i != n; ++i)
- formats.append(TypeFormatItem(reported.at(i), i));
+ formats << watchModel()->m_reportedTypeFormats.value(t);
// Fixed artificial string and pointer types.
if (origaddr || isPointerType(type)) {
@@ -1531,6 +1539,11 @@ int WatchHandler::format(const QByteArray &iname) const
return result;
}
+QString WatchHandler::nameForFormat(int format)
+{
+ return WatchModel::nameForFormat(format);
+}
+
QByteArray WatchHandler::typeFormatRequests() const
{
QByteArray ba;
@@ -1539,7 +1552,7 @@ QByteArray WatchHandler::typeFormatRequests() const
while (it.hasNext()) {
it.next();
const int format = it.value();
- if (format >= RawFormat && format < ArtificialFormatBase) {
+ if (format != AutomaticFormat) {
ba.append(it.key().toHex());
ba.append('=');
ba.append(QByteArray::number(format));
@@ -1559,7 +1572,7 @@ QByteArray WatchHandler::individualFormatRequests() const
while (it.hasNext()) {
it.next();
const int format = it.value();
- if (format >= RawFormat && format < ArtificialFormatBase) {
+ if (format != AutomaticFormat) {
ba.append(it.key());
ba.append('=');
ba.append(QByteArray::number(it.value()));
@@ -1588,7 +1601,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
while (it.hasNext()) {
it.next();
const int format = it.value();
- if (format >= RawFormat && format < ArtificialFormatBase)
+ if (format != AutomaticFormat)
cmd->arg(it.key(), format);
}
cmd->endGroup();
@@ -1598,7 +1611,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
while (it2.hasNext()) {
it2.next();
const int format = it2.value();
- if (format >= RawFormat && format < ArtificialFormatBase)
+ if (format != AutomaticFormat)
cmd->arg(it2.key(), format);
}
cmd->endGroup();
@@ -1607,20 +1620,18 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
void WatchHandler::addDumpers(const GdbMi &dumpers)
{
foreach (const GdbMi &dumper, dumpers.children()) {
- QStringList formats(tr("Raw structure"));
- foreach (const QByteArray &format, dumper["formats"].data().split(',')) {
- if (format == "Normal")
- formats.append(tr("Normal"));
- else if (format == "Displayed")
- formats.append(tr("Displayed"));
- else if (!format.isEmpty())
- formats.append(QString::fromLatin1(format));
+ DisplayFormats formats;
+ formats.append(RawFormat);
+ QByteArray reportedFormats = dumper["formats"].data();
+ foreach (const QByteArray &format, reportedFormats.split(',')) {
+ if (int f = format.toInt())
+ formats.append(DisplayFormat(f));
}
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);
}
@@ -1643,16 +1654,6 @@ QString WatchHandler::editorContents()
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()
{
m_model->m_contentsValid = false;
@@ -1698,30 +1699,6 @@ QSet<QByteArray> WatchHandler::expandedINames() const
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
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 971cacda05..c505853d6d 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -44,24 +44,49 @@ class DebuggerCommand;
class DebuggerEngine;
class WatchModel;
-class TypeFormatItem
+// Special formats. Keep in sync with dumper.py.
+enum DisplayFormat
{
-public:
- TypeFormatItem() : format(-1) {}
- TypeFormatItem(const QString &display, int format);
+ AutomaticFormat, // Based on type for individuals, dumper default for types.
+ RawFormat,
- QString display;
- int format;
-};
+ SimpleFormat, // Typical simple format (e.g. for QModelIndex row/column)
+ EnhancedFormat, // Enhanced format (e.g. for QModelIndex with resolved display)
+ SeparateFormat, // Display in separate Window
-class TypeFormatList : public QVector<TypeFormatItem>
-{
-public:
- using QVector::append;
- void append(int format);
- TypeFormatItem find(int format) const;
+ 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,
};
+typedef QVector<DisplayFormat> DisplayFormats;
+
class WatchItem : public Utils::TreeItem, public WatchData
{
public:
@@ -91,7 +116,7 @@ private:
WatchItem *parentItem() const;
const WatchModel *watchModel() const;
WatchModel *watchModel();
- TypeFormatList typeFormatList() const;
+ DisplayFormats typeFormatList() const;
bool canFetchMore() const;
QVariant data(int column, int role) const;
@@ -101,46 +126,6 @@ private:
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
{
public:
@@ -150,8 +135,6 @@ public:
QByteArray varList;
};
-typedef QHash<QString, QStringList> DumperTypeFormats; // Type name -> Dumper Formats
-
class WatchModelBase : public Utils::TreeModel
{
Q_OBJECT
@@ -201,11 +184,10 @@ public:
QByteArray individualFormatRequests() const;
int format(const QByteArray &iname) const;
+ static QString nameForFormat(int format);
void addDumpers(const GdbMi &dumpers);
- void addTypeFormats(const QByteArray &type, const QStringList &formats);
- void setTypeFormats(const DumperTypeFormats &typeFormats);
- DumperTypeFormats typeFormats() const;
+ void addTypeFormats(const QByteArray &type, const DisplayFormats &formats);
void setUnprintableBase(int base);
static int unprintableBase();
@@ -237,6 +219,6 @@ private:
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
-Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList)
+Q_DECLARE_METATYPE(Debugger::Internal::DisplayFormats)
#endif // DEBUGGER_WATCHHANDLER_H
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index c82a3fa5b9..c8f145fb29 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -554,12 +554,10 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
const QModelIndex mi2 = mi.sibling(mi.row(), 2);
const QString type = mi2.data().toString();
- const TypeFormatList alternativeFormats =
- mi.data(LocalsTypeFormatListRole).value<TypeFormatList>();
- int typeFormat =
- mi.data(LocalsTypeFormatRole).toInt();
- const int individualFormat =
- mi.data(LocalsIndividualFormatRole).toInt();
+ const DisplayFormats alternativeFormats =
+ mi.data(LocalsTypeFormatListRole).value<DisplayFormats>();
+ const int typeFormat = mi.data(LocalsTypeFormatRole).toInt();
+ const int individualFormat = mi.data(LocalsIndividualFormatRole).toInt();
const int unprintableBase = WatchHandler::unprintableBase();
QAction *showUnprintableUnicode = 0;
@@ -595,7 +593,7 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
dummy->setEnabled(false);
QString msg = (individualFormat == AutomaticFormat && typeFormat != AutomaticFormat)
? tr("Use Format for Type (Currently %1)")
- .arg(alternativeFormats.find(typeFormat).display)
+ .arg(WatchHandler::nameForFormat(typeFormat))
: tr("Use Display Format Based on Type") + QLatin1Char(' ');
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) {
- const QString display = spacer + alternativeFormats.at(i).display;
- const int format = alternativeFormats.at(i).format;
+ const int format = alternativeFormats.at(i);
+ const QString display = spacer + WatchHandler::nameForFormat(format);
QAction *act = new QAction(display, formatMenu);
act->setCheckable(true);
act->setChecked(format == individualFormat);
@@ -633,9 +631,9 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
});
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);
- const int format = alternativeFormats.at(i).format;
act->setCheckable(true);
act->setChecked(format == typeFormat);
formatMenu->addAction(act);