forked from qt-creator/qt-creator
debugger: code cosmetics for custom displays
This commit is contained in:
@@ -439,6 +439,32 @@ def findFirstZero(p, max):
|
||||
p = p + 1
|
||||
return -1
|
||||
|
||||
|
||||
def extractCharArray(p, maxsize):
|
||||
t = gdb.lookup_type("unsigned char").pointer()
|
||||
p = p.cast(t)
|
||||
i = findFirstZero(p, maxsize)
|
||||
limit = select(i < 0, maxsize, i)
|
||||
s = ""
|
||||
for i in xrange(limit):
|
||||
s += "%c" % int(p.dereference())
|
||||
p += 1
|
||||
if i == maxsize:
|
||||
s += "..."
|
||||
return s
|
||||
|
||||
def extractByteArray(value):
|
||||
d_ptr = value['d'].dereference()
|
||||
data = d_ptr['data']
|
||||
size = d_ptr['size']
|
||||
alloc = d_ptr['alloc']
|
||||
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||
checkRef(d_ptr["ref"])
|
||||
if size > 0:
|
||||
checkAccess(data, 4)
|
||||
checkAccess(data + size) == 0
|
||||
return extractCharArray(data, 100)
|
||||
|
||||
def encodeCharArray(p, maxsize, size = -1):
|
||||
t = gdb.lookup_type("unsigned char").pointer()
|
||||
p = p.cast(t)
|
||||
@@ -803,6 +829,8 @@ SalCommand()
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
StopDisplay, DisplayImage1, DisplayString, DisplayImage, DisplayProcess = range(5)
|
||||
|
||||
class Dumper:
|
||||
def __init__(self):
|
||||
self.output = ""
|
||||
@@ -907,6 +935,14 @@ class Dumper:
|
||||
str = encodeString(value)
|
||||
self.put('valueencoded="%d",value="%s",' % (7, str))
|
||||
|
||||
def putDisplay(self, format, value = None, cmd = None):
|
||||
self.put('editformat="%s",' % format)
|
||||
if cmd is None:
|
||||
if not value is None:
|
||||
self.put('editvalue="%s",' % value)
|
||||
else:
|
||||
self.put('editvalue="%s|%s",' % (cmd, value))
|
||||
|
||||
def putByteArrayValue(self, value):
|
||||
str = encodeByteArray(value)
|
||||
self.put('valueencoded="%d",value="%s",' % (6, str))
|
||||
|
||||
@@ -406,7 +406,7 @@ def qdump__QImage(d, item):
|
||||
d.endChildren()
|
||||
format = d.itemFormat(item)
|
||||
if format == 0:
|
||||
d.putField("editformat", 0) # Magic marker for "delete widget"
|
||||
d.putDisplay(StopDisplay)
|
||||
elif format == 1:
|
||||
if False:
|
||||
# Take four bytes at a time, this is critical for performance.
|
||||
@@ -428,11 +428,8 @@ def qdump__QImage(d, item):
|
||||
p = bits.cast(gdb.lookup_type("unsigned char").pointer())
|
||||
gdb.execute("dump binary memory %s %s %s" %
|
||||
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
|
||||
d.putField("editformat", 3) # Magic marker for external "QImage" data.
|
||||
d.beginItem("editvalue")
|
||||
d.put(" %d %d %d %s" % (d_ptr["width"], d_ptr["height"],
|
||||
d_ptr["format"], filename))
|
||||
d.endItem()
|
||||
d.putDisplay(DisplayImage, " %d %d %d %s"
|
||||
% (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename))
|
||||
|
||||
|
||||
def qdump__QLinkedList(d, item):
|
||||
@@ -1979,3 +1976,26 @@ def qdump__TLitC(d, item):
|
||||
d.putNumChild(0)
|
||||
d.putValue(encodeSymbianString(base, size), "7")
|
||||
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Display Test
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
if False:
|
||||
def qdump__Function(d, item):
|
||||
min = item.value["min"]
|
||||
max = item.value["max"]
|
||||
var = extractByteArray(item.value["var"])
|
||||
f = extractByteArray(item.value["f"])
|
||||
d.putValue("%s, %s=%f..%f" % (f, var, min, max))
|
||||
d.putNumChild(0)
|
||||
d.putField("typeformats", "Normal,Displayed");
|
||||
format = d.itemFormat(item)
|
||||
if format == 0:
|
||||
d.putDisplay(StopDisplay)
|
||||
elif format == 1:
|
||||
input = "plot [%s=%f:%f] %s" % (var, min, max, f)
|
||||
d.putDisplay(DisplayProcess, input, "gnuplot")
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QtAlgorithms>
|
||||
@@ -1209,12 +1210,12 @@ void WatchHandler::cleanup()
|
||||
m_watchers->m_fetchTriggered.clear();
|
||||
m_tooltips->m_fetchTriggered.clear();
|
||||
#if 1
|
||||
for (EditWindows::ConstIterator it = m_editWindows.begin();
|
||||
it != m_editWindows.end(); ++it) {
|
||||
for (EditHandlers::ConstIterator it = m_editHandlers.begin();
|
||||
it != m_editHandlers.end(); ++it) {
|
||||
if (!it.value().isNull())
|
||||
delete it.value();
|
||||
}
|
||||
m_editWindows.clear();
|
||||
m_editHandlers.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1348,21 +1349,21 @@ static void swapEndian(char *d, int nchar)
|
||||
|
||||
void WatchHandler::showEditValue(const WatchData &data)
|
||||
{
|
||||
QWidget *w = m_editWindows.value(data.iname);
|
||||
QObject *w = m_editHandlers.value(data.iname);
|
||||
if (data.editformat == 0x0) {
|
||||
m_editWindows.remove(data.iname);
|
||||
m_editHandlers.remove(data.iname);
|
||||
delete w;
|
||||
} else if (data.editformat == 0x1 || data.editformat == 0x3) {
|
||||
} else if (data.editformat == 1 || data.editformat == 3) {
|
||||
// QImage
|
||||
if (!w) {
|
||||
w = new QLabel;
|
||||
m_editWindows[data.iname] = w;
|
||||
m_editHandlers[data.iname] = w;
|
||||
}
|
||||
if (QLabel *l = qobject_cast<QLabel *>(w)) {
|
||||
int width, height, format;
|
||||
QByteArray ba;
|
||||
uchar *bits;
|
||||
if (data.editformat == 0x1) {
|
||||
if (data.editformat == 1) {
|
||||
ba = QByteArray::fromHex(data.editvalue);
|
||||
const int *header = (int *)(ba.data());
|
||||
swapEndian(ba.data(), ba.size());
|
||||
@@ -1370,7 +1371,7 @@ void WatchHandler::showEditValue(const WatchData &data)
|
||||
width = header[0];
|
||||
height = header[1];
|
||||
format = header[2];
|
||||
} else { // data.editformat == 0x3
|
||||
} else { // data.editformat == 3
|
||||
QTextStream ts(data.editvalue);
|
||||
QString fileName;
|
||||
ts >> width >> height >> format >> fileName;
|
||||
@@ -1384,11 +1385,11 @@ void WatchHandler::showEditValue(const WatchData &data)
|
||||
l->resize(width, height);
|
||||
l->show();
|
||||
}
|
||||
} else if (data.editformat == 0x2) {
|
||||
} else if (data.editformat == 2) {
|
||||
// QString
|
||||
if (!w) {
|
||||
w = new QTextEdit;
|
||||
m_editWindows[data.iname] = w;
|
||||
m_editHandlers[data.iname] = w;
|
||||
}
|
||||
QByteArray ba = QByteArray::fromHex(data.editvalue);
|
||||
QString str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2);
|
||||
@@ -1398,6 +1399,19 @@ void WatchHandler::showEditValue(const WatchData &data)
|
||||
t->resize(400, 200);
|
||||
t->show();
|
||||
}
|
||||
} else if (data.editformat == 4) {
|
||||
// Generic Process.
|
||||
int pos = data.editvalue.indexOf('|');
|
||||
QByteArray cmd = data.editvalue.left(pos);
|
||||
QByteArray input = data.editvalue.mid(pos + 1);
|
||||
QProcess *p = qobject_cast<QProcess *>(w);
|
||||
if (!p) {
|
||||
p = new QProcess;
|
||||
p->start(cmd);
|
||||
p->waitForStarted();
|
||||
m_editHandlers[data.iname] = p;
|
||||
}
|
||||
p->write(input + "\n");
|
||||
} else {
|
||||
QTC_ASSERT(false, qDebug() << "Display format: " << data.editformat);
|
||||
}
|
||||
|
||||
@@ -282,14 +282,17 @@ private:
|
||||
bool m_expandPointers;
|
||||
bool m_inChange;
|
||||
|
||||
typedef QMap<QString, QPointer<QWidget> > EditWindows;
|
||||
EditWindows m_editWindows;
|
||||
// QWidgets and QProcesses taking care of special displays.
|
||||
typedef QMap<QString, QPointer<QObject> > EditHandlers;
|
||||
EditHandlers m_editHandlers;
|
||||
|
||||
QHash<QByteArray, int> m_watcherNames;
|
||||
QByteArray watcherName(const QByteArray &exp);
|
||||
QHash<QString, int> m_typeFormats;
|
||||
QHash<QString, int> m_individualFormats;
|
||||
QSet<QByteArray> m_expandedINames; // Those expanded in the treeview.
|
||||
|
||||
// Items expanded in the Locals & Watchers view.
|
||||
QSet<QByteArray> m_expandedINames;
|
||||
|
||||
WatchModel *m_locals;
|
||||
WatchModel *m_watchers;
|
||||
|
||||
@@ -361,6 +361,28 @@ void testQImage()
|
||||
pain.end();
|
||||
}
|
||||
|
||||
struct Function
|
||||
{
|
||||
Function(QByteArray var, QByteArray f, double min, double max)
|
||||
: var(var), f(f), min(min), max(max) {}
|
||||
QByteArray var;
|
||||
QByteArray f;
|
||||
double min;
|
||||
double max;
|
||||
};
|
||||
|
||||
void testFunction()
|
||||
{
|
||||
Function func("x", "sin(x)", 0, 1);
|
||||
func.max = 10;
|
||||
func.f = "cos(x)";
|
||||
func.max = 4;
|
||||
func.max = 5;
|
||||
func.max = 6;
|
||||
func.max = 7;
|
||||
func.max = 8;
|
||||
}
|
||||
|
||||
void testIO()
|
||||
{
|
||||
qDebug() << "qDebug() 1";
|
||||
@@ -1467,6 +1489,7 @@ int main(int argc, char *argv[])
|
||||
list2 << 0;
|
||||
|
||||
testQStandardItemModel();
|
||||
testFunction();
|
||||
testQImage();
|
||||
testNoArgumentName(1, 2, 3);
|
||||
testIO();
|
||||
|
||||
Reference in New Issue
Block a user