Commit 7efeb104 authored by dt's avatar dt
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 40ff6ab2 6e93f454
......@@ -50,6 +50,7 @@
#if QT_VERSION >= 0x040500
#include <QtCore/QSharedPointer>
#include <QtCore/QSharedDataPointer>
#include <QtCore/QSharedData>
#include <QtCore/QWeakPointer>
#endif
......@@ -1345,6 +1346,11 @@ int hashOffset(bool optimizedIntKey, bool forKey, unsigned keySize, unsigned val
}
}
#ifdef Q_CC_MSVC
# define MAP_NODE_TYPE_END ">"
#else
# define MAP_NODE_TYPE_END " >"
#endif
static void qDumpQHash(QDumper &d)
{
......@@ -1407,7 +1413,7 @@ static void qDumpQHash(QDumper &d)
d.endItem();
d.beginItem("type");
d.put("'"NS"QHashNode<").put(keyType).put(",")
.put(valueType).put(" >'");
.put(valueType).put(MAP_NODE_TYPE_END"'");
d.endItem();
}
d.endHash();
......@@ -1763,7 +1769,7 @@ static void qDumpQMap(QDumper &d)
// actually, any type (even 'char') will do...
d.beginItem("type");
d.put(NS"QMapNode<").put(keyType).put(",");
d.put(valueType).put(" >");
d.put(valueType).put(MAP_NODE_TYPE_END);
d.endItem();
d.beginItem("exp");
d.put("*('"NS"QMapNode<").put(keyType).put(",");
......@@ -1776,7 +1782,7 @@ static void qDumpQMap(QDumper &d)
#else
d.beginItem("type");
d.put(NS"QMapData::Node<").put(keyType).put(",");
d.put(valueType).put(" >");
d.put(valueType).put(MAP_NODE_TYPE_END);
d.endItem();
d.beginItem("exp");
d.put("*('"NS"QMapData::Node<").put(keyType).put(",");
......@@ -3036,6 +3042,27 @@ void *watchPoint(int x, int y)
}
#endif
// Helper to write out common expression values for CDB:
// Offsets of a map node value which looks like
// "(size_t)&(('QMapNode<QString,QString >'*)0)->value")" in gdb syntax
template <class Key, class Value>
inline QDumper & putQMapNodeOffsetExpression(const char *keyType,
const char *valueType,
QDumper &d)
{
QMapNode<Key, Value> *mn = 0;
const int valueOffset = (char *)&(mn->value) - (char*)mn;
d.put("(size_t)&(('"NS"QMapNode<");
d.put(keyType);
d.put(',');
d.put(valueType);
d.put(">'*)0)->value=\"");
d.put(valueOffset);
d.put('"');
return d;
}
extern "C" Q_DECL_EXPORT
void *qDumpObjectData440(
int protocolVersion,
......@@ -3136,8 +3163,30 @@ void *qDumpObjectData440(
#endif
.put("std::string=\"").put(sizeof(std::string)).put("\",")
.put("std::wstring=\"").put(sizeof(std::wstring)).put("\",")
.put("std::allocator=\"").put(sizeof(std::allocator<int>))
.put("std::allocator=\"").put(sizeof(std::allocator<int>)).put("\",")
#if QT_VERSION >= 0x040500
.put(NS"QSharedPointer=\"").put(sizeof(QSharedPointer<int>)).put("\",")
.put(NS"QSharedDataPointer=\"").put(sizeof(QSharedDataPointer<QSharedData>)).put("\",")
.put(NS"QWeakPointer=\"").put(sizeof(QWeakPointer<int>)).put("\",")
#endif
.put("QPointer=\"").put(sizeof(QPointer<QObject>)).put("\",")
// Common map node types
.put(NS"QMapNode<int,int>=\"").put(sizeof(QMapNode<int,int >)).put("\",")
.put(NS"QMapNode<int,"NS"QString>=\"").put(sizeof(QMapNode<int, QString>)).put("\",")
.put(NS"QMapNode<int,"NS"QVariant>=\"").put(sizeof(QMapNode<int, QVariant>)).put("\",")
.put(NS"QMapNode<"NS"QString,int>=\"").put(sizeof(QMapNode<QString, int>)).put("\",")
.put(NS"QMapNode<"NS"QString,"NS"QString>=\"").put(sizeof(QMapNode<QString, QString>)).put("\",")
.put(NS"QMapNode<"NS"QString,"NS"QVariant>=\"").put(sizeof(QMapNode<QString, QVariant>))
.put("\"}");
// Write out common expression values for CDB
d.put(",expressions={");
putQMapNodeOffsetExpression<int,int>("int", "int", d).put(',');
putQMapNodeOffsetExpression<int,QString>("int", NS"QString", d).put(',');
putQMapNodeOffsetExpression<int,QVariant>("int", NS"QVariant", d).put(',');
putQMapNodeOffsetExpression<QString,int>(NS"QString", "int", d).put(',');
putQMapNodeOffsetExpression<QString,QString>(NS"QString", NS"QString", d).put(',');
putQMapNodeOffsetExpression<QString,QVariant>(NS"QString", NS"QVariant", d);
d.put('}');
d.disarm();
}
......
......@@ -29,12 +29,15 @@
#include <QtCore/QStringList>
#include <QtCore/QVector>
#include <QtCore/QSharedPointer>
#include <QtCore/QTimer>
#include <QtCore/QMap>
#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <stdio.h>
#include <string.h>
......@@ -102,6 +105,17 @@ static int dumpQString()
return 0;
}
static int dumpQSharedPointerQString()
{
QSharedPointer<QString> test(new QString(QLatin1String("hallo")));
prepareInBuffer("QSharedPointer", "local.sharedpointerqstring", "local.local.sharedpointerqstring", "QString");
qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0);
fputs(qDumpOutBuffer, stdout);
fputc('\n', stdout);
QString uninitialized;
return 0;
}
static int dumpQStringList()
{
QStringList test = QStringList() << QLatin1String("item1") << QLatin1String("item2");
......@@ -132,6 +146,34 @@ static int dumpQIntVector()
return 0;
}
static int dumpQMapIntInt()
{
QMap<int,int> test;
QMapNode<int,int> mapNode;
const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode;
test.insert(42, 43);
test.insert(43, 44);
prepareInBuffer("QMap", "local.qmapintint", "local.qmapintint", "int@int");
qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(int), sizeof(mapNode), valueOffset);
fputs(qDumpOutBuffer, stdout);
fputc('\n', stdout);
return 0;
}
static int dumpQMapIntString()
{
QMap<int,QString> test;
QMapNode<int,QString> mapNode;
const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode;
test.insert(42, QLatin1String("fortytwo"));
test.insert(43, QLatin1String("fortytree"));
prepareInBuffer("QMap", "local.qmapintqstring", "local.qmapintqstring", "int@QString");
qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(QString), sizeof(mapNode), valueOffset);
fputs(qDumpOutBuffer, stdout);
fputc('\n', stdout);
return 0;
}
// --------------- std types
static int dumpStdString()
......@@ -238,6 +280,20 @@ static int dumpStdStringSet()
return 0;
}
static int dumpStdMapIntString()
{
std::map<int,std::string> test;
std::map<int,std::string>::value_type entry(42, std::string("fortytwo"));
test.insert(entry);
const int valueOffset = (char*)&(entry.second) - (char*)&entry;
prepareInBuffer("std::map", "local.stdmapintstring", "local.stdmapintstring",
"int@std::basic_string<char,std::char_traits<char>,std::allocator<char> >@std::less<int>@std::allocator<std::pair<const int,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >");
qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::string), valueOffset, 0);
fputs(qDumpOutBuffer, stdout);
fputc('\n', stdout);
return 0;
}
static int dumpQObject()
{
// Requires the childOffset to be know, but that is not critical
......@@ -249,6 +305,47 @@ static int dumpQObject()
return 0;
}
static bool dumpType(const char *arg)
{
if (!qstrcmp(arg, "QString"))
{ dumpQString(); return true; }
if (!qstrcmp(arg, "QSharedPointer<QString>"))
{ dumpQSharedPointerQString(); return true; }
if (!qstrcmp(arg, "QStringList"))
{ dumpQStringList(); return true; }
if (!qstrcmp(arg, "QList<int>"))
{ dumpQIntList(); return true; }
if (!qstrcmp(arg, "QList<std::string>"))
{ dumpStdStringQList(); return true; }
if (!qstrcmp(arg, "QVector<int>"))
{ dumpQIntVector(); return true; }
if (!qstrcmp(arg, "QMap<int,QString>"))
{ dumpQMapIntString(); return true; }
if (!qstrcmp(arg, "QMap<int,int>"))
{ dumpQMapIntInt(); return true; }
if (!qstrcmp(arg, "string"))
{ dumpStdString(); return true; }
if (!qstrcmp(arg, "wstring"))
{ dumpStdWString(); return true; }
if (!qstrcmp(arg, "list<int>"))
{ dumpStdIntList(); return true; }
if (!qstrcmp(arg, "list<string>"))
{ dumpStdStringList(); return true; }
if (!qstrcmp(arg, "vector<int>"))
{ dumpStdIntVector(); return true; }
if (!qstrcmp(arg, "vector<string>"))
{ dumpStdStringVector(); return true; }
if (!qstrcmp(arg, "set<int>"))
{ dumpStdIntSet(); return true; }
if (!qstrcmp(arg, "set<string>"))
{ dumpStdStringSet(); return true; }
if (!qstrcmp(arg, "map<int,string>"))
{ dumpStdMapIntString(); return true; }
if (!qstrcmp(arg, "QObject"))
{ dumpQObject(); return true; }
return false;
}
int main(int argc, char *argv[])
{
printf("Running query protocol\n");
......@@ -266,34 +363,8 @@ int main(int argc, char *argv[])
continue;
}
printf("\nTesting %s\n", arg);
if (!qstrcmp(arg, "QString"))
dumpQString();
if (!qstrcmp(arg, "QStringList"))
dumpQStringList();
if (!qstrcmp(arg, "QList<int>"))
dumpQIntList();
if (!qstrcmp(arg, "QList<std::string>"))
dumpStdStringQList();
if (!qstrcmp(arg, "QVector<int>"))
dumpQIntVector();
if (!qstrcmp(arg, "string"))
dumpStdString();
if (!qstrcmp(arg, "wstring"))
dumpStdWString();
if (!qstrcmp(arg, "list<int>"))
dumpStdIntList();
if (!qstrcmp(arg, "list<string>"))
dumpStdStringList();
if (!qstrcmp(arg, "vector<int>"))
dumpStdIntVector();
if (!qstrcmp(arg, "vector<string>"))
dumpStdStringVector();
if (!qstrcmp(arg, "set<int>"))
dumpStdIntSet();
if (!qstrcmp(arg, "set<string>"))
dumpStdStringSet();
if (!qstrcmp(arg, "QObject"))
dumpQObject();
if (!dumpType(arg))
printf("\nUnhandled type: %s\n", arg);
}
return 0;
}
......@@ -654,6 +654,48 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
static_cast<QHBoxLayout*>(w->layout())->insertWidget(0, m_methodCombo, 1);
}
void CPPEditor::inAllRenameSelections(EditOperation operation,
const QTextEdit::ExtraSelection &currentRenameSelection,
QTextCursor cursor,
const QString &text)
{
m_inRename = true;
cursor.beginEditBlock();
const int offset = cursor.position() - currentRenameSelection.cursor.anchor();
for (int i = 0; i < m_renameSelections.size(); ++i) {
QTextEdit::ExtraSelection &s = m_renameSelections[i];
int pos = s.cursor.anchor();
int endPos = s.cursor.position();
s.cursor.setPosition(s.cursor.anchor() + offset);
switch (operation) {
case DeletePreviousChar:
s.cursor.deletePreviousChar();
--endPos;
break;
case DeleteChar:
s.cursor.deleteChar();
--endPos;
break;
case InsertText:
s.cursor.insertText(text);
endPos += text.length();
break;
}
s.cursor.setPosition(pos);
s.cursor.setPosition(endPos, QTextCursor::KeepAnchor);
}
cursor.endEditBlock();
m_inRename = false;
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
setTextCursor(cursor);
}
void CPPEditor::abortRename()
{
m_currentRenameSelection = -1;
......@@ -805,7 +847,7 @@ void CPPEditor::renameInPlace()
for (int i = 0; i < m_renameSelections.size(); ++i) {
QTextEdit::ExtraSelection s = m_renameSelections.at(i);
if (c.position() >= s.cursor.anchor()
&& c.position() < s.cursor.position()) {
&& c.position() <= s.cursor.position()) {
m_currentRenameSelection = i;
m_renameSelections[i].format.setBackground(QColor(255, 200, 200));
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
......@@ -816,6 +858,9 @@ void CPPEditor::renameInPlace()
void CPPEditor::onContentsChanged(int position, int charsRemoved, int charsAdded)
{
Q_UNUSED(position)
Q_UNUSED(charsAdded)
if (!m_inRename)
abortRename();
......@@ -1372,10 +1417,6 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
foreach (QAction *action, contextMenu->actions())
menu->addAction(action);
QAction *simplifyDeclarations = new QAction(tr("Simplify Declarations"), menu);
connect(simplifyDeclarations, SIGNAL(triggered()), this, SLOT(simplifyDeclarations()));
menu->addAction(simplifyDeclarations);
const QList<QTextEdit::ExtraSelection> selections =
extraSelections(BaseTextEditor::CodeSemanticsSelection);
......@@ -1458,9 +1499,10 @@ void CPPEditor::keyPressEvent(QKeyEvent *e)
return;
}
QTextEdit::ExtraSelection currentRenameSelection = m_renameSelections.at(m_currentRenameSelection);
QTextCursor::MoveMode moveMode = (e->modifiers() & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor;
const QTextEdit::ExtraSelection &currentRenameSelection = m_renameSelections.at(m_currentRenameSelection);
QTextCursor cursor = textCursor();
const QTextCursor::MoveMode moveMode =
(e->modifiers() & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor;
switch (e->key()) {
case Qt::Key_Enter:
......@@ -1470,86 +1512,50 @@ void CPPEditor::keyPressEvent(QKeyEvent *e)
e->accept();
return;
case Qt::Key_Home: {
QTextCursor c = textCursor();
c.setPosition(currentRenameSelection.cursor.anchor(), moveMode);
setTextCursor(c);
e->accept();
return;
// Send home to start of name when within the name and not at the start
if (cursor.position() > currentRenameSelection.cursor.anchor()
&& cursor.position() <= currentRenameSelection.cursor.position()) {
cursor.setPosition(currentRenameSelection.cursor.anchor(), moveMode);
setTextCursor(cursor);
e->accept();
return;
}
break;
}
case Qt::Key_End: {
QTextCursor c = textCursor();
c.setPosition(currentRenameSelection.cursor.position(), moveMode);
setTextCursor(c);
e->accept();
return;
// Send end to end of name when within the name and not at the end
if (cursor.position() >= currentRenameSelection.cursor.anchor()
&& cursor.position() < currentRenameSelection.cursor.position()) {
cursor.setPosition(currentRenameSelection.cursor.position(), moveMode);
setTextCursor(cursor);
e->accept();
return;
}
break;
}
case Qt::Key_Backspace: {
QTextCursor c = textCursor();
if (c.position() == currentRenameSelection.cursor.anchor()) {
// Eat
if (cursor.position() == currentRenameSelection.cursor.anchor()) {
// Eat backspace at start of name
e->accept();
return;
} else if (c.position() > currentRenameSelection.cursor.anchor()
&& c.position() <= currentRenameSelection.cursor.position()) {
int offset = c.position() - currentRenameSelection.cursor.anchor();
m_inRename = true;
c.beginEditBlock();
for (int i = 0; i < m_renameSelections.size(); ++i) {
QTextEdit::ExtraSelection &s = m_renameSelections[i];
int pos = s.cursor.anchor();
int endPos = s.cursor.position();
s.cursor.setPosition(s.cursor.anchor() + offset);
s.cursor.deletePreviousChar();
s.cursor.setPosition(pos);
s.cursor.setPosition(endPos - 1, QTextCursor::KeepAnchor);
}
c.endEditBlock();
m_inRename = false;
setTextCursor(c);
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
} else if (cursor.position() > currentRenameSelection.cursor.anchor()
&& cursor.position() <= currentRenameSelection.cursor.position()) {
inAllRenameSelections(DeletePreviousChar, currentRenameSelection, cursor);
e->accept();
return;
}
break;
}
case Qt::Key_Delete: {
QTextCursor c = textCursor();
if (c.position() == currentRenameSelection.cursor.position()) {
// Eat
if (cursor.position() == currentRenameSelection.cursor.position()) {
// Eat delete at end of name
e->accept();
return;
} else if (c.position() >= currentRenameSelection.cursor.anchor()
&& c.position() < currentRenameSelection.cursor.position()) {
int offset = c.position() - currentRenameSelection.cursor.anchor();
m_inRename = true;
c.beginEditBlock();
for (int i = 0; i < m_renameSelections.size(); ++i) {
QTextEdit::ExtraSelection &s = m_renameSelections[i];
int pos = s.cursor.anchor();
int endPos = s.cursor.position();
s.cursor.setPosition(s.cursor.anchor() + offset);
s.cursor.deleteChar();
s.cursor.setPosition(pos);
s.cursor.setPosition(endPos - 1, QTextCursor::KeepAnchor);
}
c.endEditBlock();
m_inRename = false;
setTextCursor(c);
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
} else if (cursor.position() >= currentRenameSelection.cursor.anchor()
&& cursor.position() < currentRenameSelection.cursor.position()) {
inAllRenameSelections(DeleteChar, currentRenameSelection, cursor);
e->accept();
return;
}
......@@ -1557,34 +1563,11 @@ void CPPEditor::keyPressEvent(QKeyEvent *e)
}
default: {
QString text = e->text();
if (! text.isEmpty() && text.at(0).isPrint()) {
QTextCursor c = textCursor();
if (c.position() >= currentRenameSelection.cursor.anchor()
&& c.position() <= currentRenameSelection.cursor.position()) {
int offset = c.position() - currentRenameSelection.cursor.anchor();
m_inRename = true;
c.beginEditBlock();
for (int i = 0; i < m_renameSelections.size(); ++i) {
QTextEdit::ExtraSelection &s = m_renameSelections[i];
int pos = s.cursor.anchor();
int endPos = s.cursor.position();
s.cursor.setPosition(s.cursor.anchor() + offset);
s.cursor.insertText(text);
s.cursor.setPosition(pos);
s.cursor.setPosition(endPos + text.length(), QTextCursor::KeepAnchor);
}
c.endEditBlock();
m_inRename = false;
setTextCursor(c);
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
if (cursor.position() >= currentRenameSelection.cursor.anchor()
&& cursor.position() <= currentRenameSelection.cursor.position()) {
inAllRenameSelections(InsertText, currentRenameSelection, cursor, text);
e->accept();
return;
}
......
......@@ -143,6 +143,15 @@ private:
void createToolBar(CPPEditorEditable *editable);
enum EditOperation {
DeleteChar,
DeletePreviousChar,
InsertText
};
void inAllRenameSelections(EditOperation operation,
const QTextEdit::ExtraSelection &currentRenameSelection,
QTextCursor cursor,
const QString &text = QString());
void abortRename();
struct Link
......
......@@ -576,8 +576,9 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool
return DumpOk;
// Cache types that fail due to complicated template size expressions.
// Exceptions OTOH might occur when accessing variables that are not
// yet initialized in a particular breakpoint. That should be ignored
if (der == DumpExecuteSizeFailed)
// yet initialized in a particular breakpoint. That should be ignored.
// Also fail for complex expression that were not cached/replaced by the helper.
if (der == DumpExecuteSizeFailed || der == DumpComplexExpressionEncountered)
m_failedTypes.push_back(wd.type);
// log error
*errorMessage = msgDumpFailed(wd, errorMessage);
......@@ -611,6 +612,12 @@ CdbDumperHelper::DumpExecuteResult
if (!sizeOk)
return DumpExecuteSizeFailed;
ep = QString::number(size);
continue;
}
// We cannot evaluate any other expressions than 'sizeof()' ;-(
if (!ep.isEmpty() && !ep.at(0).isDigit()) {
*errorMessage = QString::fromLatin1("Unable to evaluate: '%1'").arg(ep);
return DumpComplexExpressionEncountered;
}
}
// Execute call
......
......@@ -109,7 +109,9 @@ private:
bool callDumper(const QString &call, const QByteArray &inBuffer, const char **outputPtr,
bool ignoreAccessViolation, QString *errorMessage);
enum DumpExecuteResult { DumpExecuteOk, DumpExecuteSizeFailed, DumpExecuteCallFailed };
enum DumpExecuteResult { DumpExecuteOk, DumpExecuteSizeFailed,
DumpComplexExpressionEncountered,
DumpExecuteCallFailed };
DumpExecuteResult executeDump(const WatchData &wd,
const QtDumperHelper::TypeData& td, bool dumpChildren, int source,
QList<WatchData> *result, QString *errorMessage);
......
......@@ -112,7 +112,7 @@ WatchHandleDumperInserter::WatchHandleDumperInserter(WatchHandler *wh,
const SharedPointerCdbDumperHelper &dumper) :
m_hexNullPattern(QLatin1String("0x0+")),
m_wh(wh),
m_dumper(dumper)
m_dumper(dumper)
{
Q_ASSERT(m_hexNullPattern.isValid());
}
......@@ -179,6 +179,10 @@ WatchHandleDumperInserter &WatchHandleDumperInserter::operator=(WatchData &wd)
case CdbDumperHelper::DumpOk:
if (debugCDBWatchHandling)
qDebug() << "dumper triggered";