forked from qt-creator/qt-creator
debugger: speed up QDate, QTime, QDateTime dumpers
Change-Id: I9ed3961d047738bd3add87b1f00d548df1fb01d8 Reviewed-on: http://codereview.qt.nokia.com/3609 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -66,8 +66,11 @@ Hex2EncodedUtf8, \
|
||||
Hex8EncodedBigEndian, \
|
||||
Hex4EncodedBigEndian, \
|
||||
Hex4EncodedLittleEndianWithoutQuotes, \
|
||||
Hex2EncodedLocal8Bit \
|
||||
= range(14)
|
||||
Hex2EncodedLocal8Bit, \
|
||||
JulianDate, \
|
||||
MillisecondsSinceMidnight, \
|
||||
JulianDateAndMillisecondsSinceMidnight \
|
||||
= range(17)
|
||||
|
||||
# Display modes
|
||||
StopDisplay, \
|
||||
|
@@ -139,14 +139,10 @@ def qdump__QModelIndex(d, value):
|
||||
|
||||
|
||||
def qdump__QDate(d, value):
|
||||
if int(value["jd"]) == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
qt = d.ns + "Qt::"
|
||||
d.putStringValue(call(value, "toString", qt + "TextDate"))
|
||||
d.putValue(value["jd"], JulianDate)
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
qt = d.ns + "Qt::"
|
||||
# FIXME: This improperly uses complex return values.
|
||||
with Children(d):
|
||||
d.putCallItem("toString", value, "toString", qt + "TextDate")
|
||||
@@ -157,14 +153,10 @@ def qdump__QDate(d, value):
|
||||
|
||||
|
||||
def qdump__QTime(d, value):
|
||||
if int(value["mds"]) == -1:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
qt = d.ns + "Qt::"
|
||||
d.putStringValue(call(value, "toString", qt + "TextDate"))
|
||||
d.putValue(value["mds"], MillisecondsSinceMidnight)
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
qt = d.ns + "Qt::"
|
||||
# FIXME: This improperly uses complex return values.
|
||||
with Children(d):
|
||||
d.putCallItem("toString", value, "toString", qt + "TextDate")
|
||||
@@ -178,19 +170,17 @@ def qdump__QTime(d, value):
|
||||
def qdump__QDateTime(d, value):
|
||||
try:
|
||||
# Fails without debug info.
|
||||
if int(value["d"]["d"].dereference()["time"]["mds"]) == -1:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
p = value["d"]["d"].dereference()
|
||||
except:
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
qt = d.ns + "Qt::"
|
||||
d.putStringValue(call(value, "toString", qt + "TextDate"))
|
||||
d.putValue("%s/%s" % (p["date"]["jd"], p["time"]["mds"]),
|
||||
JulianDateAndMillisecondsSinceMidnight)
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
# FIXME: This improperly uses complex return values.
|
||||
with Children(d):
|
||||
qt = d.ns + "Qt::"
|
||||
d.putCallItem("toTime_t", value, "toTime_t")
|
||||
d.putCallItem("toString", value, "toString", qt + "TextDate")
|
||||
d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
|
||||
|
@@ -274,25 +274,25 @@ static QString niceTypeHelper(const QByteArray &typeIn)
|
||||
return simplified;
|
||||
}
|
||||
|
||||
static QString removeNamespaces(QString str, const QByteArray &ns)
|
||||
QString WatchModel::removeNamespaces(QString str) const
|
||||
{
|
||||
if (!debuggerCore()->boolSetting(ShowStdNamespace))
|
||||
str.remove(QLatin1String("std::"));
|
||||
if (!debuggerCore()->boolSetting(ShowQtNamespace)) {
|
||||
const QString qtNamespace = QString::fromLatin1(ns);
|
||||
const QString qtNamespace = QString::fromLatin1(engine()->qtNamespace());
|
||||
if (!qtNamespace.isEmpty())
|
||||
str.remove(qtNamespace);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static QString removeInitialNamespace(QString str, const QByteArray &ns)
|
||||
QString WatchModel::removeInitialNamespace(QString str) const
|
||||
{
|
||||
if (str.startsWith(QLatin1String("std::"))
|
||||
&& debuggerCore()->boolSetting(ShowStdNamespace))
|
||||
str = str.mid(5);
|
||||
if (!debuggerCore()->boolSetting(ShowQtNamespace)) {
|
||||
const QString qtNamespace = QString::fromLatin1(ns);
|
||||
const QByteArray qtNamespace = engine()->qtNamespace();
|
||||
if (!qtNamespace.isEmpty() && str.startsWith(qtNamespace))
|
||||
str = str.mid(qtNamespace.size());
|
||||
}
|
||||
@@ -395,41 +395,45 @@ static QString quoteUnprintable(const QString &str)
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static QString formattedValue(const WatchData &data, int format)
|
||||
QString WatchModel::formattedValue(const WatchData &data) const
|
||||
{
|
||||
const QByteArray qtNamespace = engine()->qtNamespace();
|
||||
const QString &value = data.value;
|
||||
|
||||
int format = itemFormat(data);
|
||||
if (isIntType(data.type)) {
|
||||
if (data.value.isEmpty())
|
||||
return data.value;
|
||||
if (value.isEmpty())
|
||||
return value;
|
||||
// Do not reformat booleans (reported as 'true, false').
|
||||
const QChar firstChar = data.value.at(0);
|
||||
const QChar firstChar = value.at(0);
|
||||
if (!firstChar.isDigit() && firstChar != QLatin1Char('-'))
|
||||
return data.value;
|
||||
return value;
|
||||
// Append quoted, printable character also for decimal.
|
||||
if (data.type.endsWith("char")) {
|
||||
bool ok;
|
||||
const int code = data.value.toInt(&ok);
|
||||
return ok ? reformatCharacter(code, format) : data.value;
|
||||
const int code = value.toInt(&ok);
|
||||
return ok ? reformatCharacter(code, format) : value;
|
||||
}
|
||||
// Rest: Leave decimal as is
|
||||
if (format <= 0)
|
||||
return data.value;
|
||||
return value;
|
||||
// Evil hack, covers 'unsigned' as well as quint64.
|
||||
if (data.type.contains('u'))
|
||||
return reformatInteger(data.value.toULongLong(0, 0), format);
|
||||
return reformatInteger(data.value.toLongLong(), format);
|
||||
return reformatInteger(value.toULongLong(0, 0), format);
|
||||
return reformatInteger(value.toLongLong(), format);
|
||||
}
|
||||
|
||||
if (data.type == "va_list")
|
||||
return data.value;
|
||||
return value;
|
||||
|
||||
if (!isPointerType(data.type) && !isVTablePointer(data.type)) {
|
||||
bool ok = false;
|
||||
qulonglong integer = data.value.toULongLong(&ok, 0);
|
||||
qulonglong integer = value.toULongLong(&ok, 0);
|
||||
if (ok)
|
||||
return reformatInteger(integer, format);
|
||||
}
|
||||
|
||||
QString result = data.value;
|
||||
QString result = value;
|
||||
if (result.startsWith(QLatin1Char('<'))) {
|
||||
if (result == QLatin1String("<Edit>"))
|
||||
result = WatchHandler::tr("<Edit>");
|
||||
@@ -446,7 +450,8 @@ static QString formattedValue(const WatchData &data, int format)
|
||||
bool ok;
|
||||
const bool moreThan = result.at(1) == QLatin1Char('>');
|
||||
const int numberPos = moreThan ? 2 : 1;
|
||||
const int size = result.mid(numberPos, result.indexOf(' ') - numberPos).toInt(&ok);
|
||||
const int len = result.indexOf(' ') - numberPos;
|
||||
const int size = result.mid(numberPos, len).toInt(&ok);
|
||||
QTC_ASSERT(ok, qWarning("WatchHandler: Invalid item count '%s'",
|
||||
qPrintable(result)))
|
||||
result = moreThan ?
|
||||
@@ -629,8 +634,8 @@ void WatchModel::emitDataChanged(int column, const QModelIndex &parentIndex)
|
||||
emitDataChanged(column, index(i, 0, parentIndex));
|
||||
}
|
||||
|
||||
// Truncate value for item view, maintaining quotes
|
||||
static inline QString truncateValue(QString v)
|
||||
// Truncate value for item view, maintaining quotes.
|
||||
static QString truncateValue(QString v)
|
||||
{
|
||||
enum { maxLength = 512 };
|
||||
if (v.size() < maxLength)
|
||||
@@ -699,7 +704,6 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
|
||||
}
|
||||
|
||||
case Qt::DisplayRole: {
|
||||
const QByteArray qtNameSpace = engine()->qtNamespace();
|
||||
QString result;
|
||||
switch (idx.column()) {
|
||||
case 0:
|
||||
@@ -708,18 +712,18 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
|
||||
else if (data.name == QLatin1String("*") && item->parent)
|
||||
result = QLatin1Char('*') + item->parent->name;
|
||||
else
|
||||
result = removeInitialNamespace(data.name, qtNameSpace);
|
||||
result = removeInitialNamespace(data.name);
|
||||
break;
|
||||
case 1:
|
||||
result = removeInitialNamespace(truncateValue(
|
||||
formattedValue(data, itemFormat(data))), qtNameSpace);
|
||||
result = removeInitialNamespace(
|
||||
truncateValue(formattedValue(data)));
|
||||
if (data.referencingAddress) {
|
||||
result += QLatin1String(" @");
|
||||
result += QString::fromLatin1(data.hexAddress());
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
result = removeNamespaces(displayType(data), qtNameSpace);
|
||||
result = removeNamespaces(displayType(data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -787,7 +791,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
|
||||
return m_handler->m_reportedTypeFormats.value(type);
|
||||
}
|
||||
case LocalsTypeRole:
|
||||
return removeNamespaces(displayType(data), engine()->qtNamespace());
|
||||
return removeNamespaces(displayType(data));
|
||||
case LocalsRawTypeRole:
|
||||
return QString::fromLatin1(data.type);
|
||||
case LocalsTypeFormatRole:
|
||||
|
@@ -121,6 +121,9 @@ signals:
|
||||
|
||||
private:
|
||||
QString displayType(const WatchData &typeIn) const;
|
||||
QString formattedValue(const WatchData &data) const;
|
||||
QString removeInitialNamespace(QString str) const;
|
||||
QString removeNamespaces(QString str) const;
|
||||
void formatRequests(QByteArray *out, const WatchItem *item) const;
|
||||
DebuggerEngine *engine() const;
|
||||
int itemFormat(const WatchData &data) const;
|
||||
|
@@ -55,12 +55,13 @@
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QTime>
|
||||
|
||||
#include <QtGui/QTextCursor>
|
||||
#include <QtGui/QPlainTextEdit>
|
||||
@@ -518,6 +519,16 @@ QString quoteUnprintableLatin1(const QByteArray &ba)
|
||||
return res;
|
||||
}
|
||||
|
||||
static QDate dateFromData(int jd)
|
||||
{
|
||||
return jd ? QDate::fromJulianDay(jd) : QDate();
|
||||
}
|
||||
|
||||
static QTime timeFromData(int ms)
|
||||
{
|
||||
return ms == -1 ? QTime() : QTime(0, 0, 0, 0).addMSecs(ms);
|
||||
}
|
||||
|
||||
QString decodeData(const QByteArray &ba, int encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
@@ -613,6 +624,20 @@ QString decodeData(const QByteArray &ba, int encoding)
|
||||
const QByteArray decodedBa = QByteArray::fromHex(ba);
|
||||
return doubleQuote + QString::fromLocal8Bit(decodedBa) + doubleQuote;
|
||||
}
|
||||
case JulianDate: { // 14, an integer count
|
||||
const QDate date = dateFromData(ba.toInt());
|
||||
return date.toString(Qt::TextDate);
|
||||
}
|
||||
case MillisecondsSinceMidnight: {
|
||||
const QTime time = timeFromData(ba.toInt());
|
||||
return time.toString(Qt::TextDate);
|
||||
}
|
||||
case JulianDateAndMillisecondsSinceMidnight: {
|
||||
const int p = ba.indexOf('/');
|
||||
const QDate date = dateFromData(ba.left(p).toInt());
|
||||
const QTime time = timeFromData(ba.mid(p + 1 ).toInt());
|
||||
return QDateTime(date, time).toString(Qt::TextDate);
|
||||
}
|
||||
}
|
||||
qDebug() << "ENCODING ERROR: " << encoding;
|
||||
return QCoreApplication::translate("Debugger", "<Encoding error>");
|
||||
|
@@ -56,20 +56,23 @@ class GdbMi;
|
||||
// Keep in sync with dumper.py
|
||||
enum DebuggerEncoding
|
||||
{
|
||||
Unencoded8Bit = 0,
|
||||
Base64Encoded8BitWithQuotes = 1,
|
||||
Base64Encoded16BitWithQuotes = 2,
|
||||
Base64Encoded32BitWithQuotes = 3,
|
||||
Base64Encoded16Bit = 4,
|
||||
Base64Encoded8Bit = 5,
|
||||
Hex2EncodedLatin1WithQuotes = 6,
|
||||
Hex4EncodedLittleEndianWithQuotes = 7,
|
||||
Hex8EncodedLittleEndianWithQuotes = 8,
|
||||
Hex2EncodedUtf8WithQuotes = 9,
|
||||
Hex8EncodedBigEndian = 10,
|
||||
Hex4EncodedBigEndianWithQuotes = 11,
|
||||
Hex4EncodedLittleEndianWithoutQuotes = 12,
|
||||
Hex2EncodedLocal8BitWithQuotes = 13
|
||||
Unencoded8Bit = 0,
|
||||
Base64Encoded8BitWithQuotes = 1,
|
||||
Base64Encoded16BitWithQuotes = 2,
|
||||
Base64Encoded32BitWithQuotes = 3,
|
||||
Base64Encoded16Bit = 4,
|
||||
Base64Encoded8Bit = 5,
|
||||
Hex2EncodedLatin1WithQuotes = 6,
|
||||
Hex4EncodedLittleEndianWithQuotes = 7,
|
||||
Hex8EncodedLittleEndianWithQuotes = 8,
|
||||
Hex2EncodedUtf8WithQuotes = 9,
|
||||
Hex8EncodedBigEndian = 10,
|
||||
Hex4EncodedBigEndianWithQuotes = 11,
|
||||
Hex4EncodedLittleEndianWithoutQuotes = 12,
|
||||
Hex2EncodedLocal8BitWithQuotes = 13,
|
||||
JulianDate = 14,
|
||||
MillisecondsSinceMidnight = 15,
|
||||
JulianDateAndMillisecondsSinceMidnight = 16
|
||||
};
|
||||
|
||||
bool isEditorDebuggable(Core::IEditor *editor);
|
||||
|
@@ -40,13 +40,13 @@
|
||||
// lines containing the BREAK_HERE macro. This should be enabled
|
||||
// during manual testing.
|
||||
// Default: 1
|
||||
#define USE_AUTOBREAK 1
|
||||
#define USE_AUTOBREAK 0
|
||||
|
||||
// With USE_UNINITIALIZE_AUTOBREAK, the debugger will stop automatically
|
||||
// on all lines containing the BREAK_UNINITIALIZED_HERE macro.
|
||||
// This should be enabled during manual testing.
|
||||
// Default: 1
|
||||
#define USE_UNINITIALIZED_AUTOBREAK 1
|
||||
#define USE_UNINITIALIZED_AUTOBREAK 0
|
||||
|
||||
// With USE_PRIVATE tests that require private headers are enabled.
|
||||
// Default: 1
|
||||
@@ -2758,7 +2758,7 @@ namespace basic {
|
||||
QDateTime time = QDateTime::currentDateTime();
|
||||
const int N = 10000;
|
||||
QDateTime bigv[N];
|
||||
for (int i = 0; i < N; ++i) {
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
bigv[i] = time;
|
||||
time.addDays(1);
|
||||
}
|
||||
@@ -2772,7 +2772,7 @@ namespace basic {
|
||||
{
|
||||
const int N = 10000;
|
||||
int bigv[N];
|
||||
for (int i = 0; i < N; ++i)
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
bigv[i] = i;
|
||||
BREAK_HERE;
|
||||
// Expand bigv.
|
||||
|
Reference in New Issue
Block a user