Merge branch 'master' of ../mainline into dui-editor

This commit is contained in:
Roberto Raggi
2009-04-30 12:12:19 +02:00
17 changed files with 791 additions and 128 deletions

View File

@@ -56,6 +56,7 @@
int qtGhVersion = QT_VERSION;
#ifdef QT_GUI_LIB
# include <QtGui/QWidget>
# include <QtGui/QPixmap>
# include <QtGui/QImage>
#endif
@@ -2186,6 +2187,44 @@ static void qDumpQVector(QDumper &d)
d.disarm();
}
static void qDumpQWeakPointer(QDumper &d)
{
const int v = sizeof(void *);
const void *value = deref(addOffset(d.data, v));
if (isSimpleType(d.innertype))
qDumpInnerValueHelper(d, d.innertype, value);
else
P(d, "value", "");
P(d, "valuedisabled", "true");
P(d, "numchild", 1);
if (d.dumpChildren) {
d << ",children=[";
d.beginHash();
P(d, "name", "data");
qDumpInnerValue(d, d.innertype, value);
d.endHash();
d.beginHash();
const void *weak = addOffset(deref(d.data), v);
P(d, "name", "weakref");
P(d, "value", *static_cast<const int *>(weak));
P(d, "type", "int");
P(d, "addr", weak);
P(d, "numchild", "0");
d.endHash();
d.beginHash();
const void *strong = addOffset(weak, sizeof(int));
P(d, "name", "strongref");
P(d, "value", *static_cast<const int *>(strong));
P(d, "type", "int");
P(d, "addr", strong);
P(d, "numchild", "0");
d.endHash();
d << "]";
}
d.disarm();
}
static void qDumpStdList(QDumper &d)
{
const std::list<int> &list = *reinterpret_cast<const std::list<int> *>(d.data);
@@ -2558,16 +2597,6 @@ static void handleProtocolVersion2and3(QDumper & d)
else if (isEqual(type, "QStringList"))
qDumpQStringList(d);
break;
case 'T':
if (isEqual(type, "QTextCodec"))
qDumpQTextCodec(d);
break;
case 'V':
if (isEqual(type, "QVariant"))
qDumpQVariant(d);
else if (isEqual(type, "QVector"))
qDumpQVector(d);
break;
case 's':
if (isEqual(type, "wstring"))
qDumpStdWString(d);
@@ -2588,6 +2617,19 @@ static void handleProtocolVersion2and3(QDumper & d)
else if (isEqual(type, "std::wstring"))
qDumpStdWString(d);
break;
case 'T':
if (isEqual(type, "QTextCodec"))
qDumpQTextCodec(d);
break;
case 'V':
if (isEqual(type, "QVariant"))
qDumpQVariant(d);
else if (isEqual(type, "QVector"))
qDumpQVector(d);
break;
case 'W':
if (isEqual(type, "QWeakPointer"))
qDumpQWeakPointer(d);
}
if (!d.success)
@@ -2663,6 +2705,7 @@ void *qDumpObjectData440(
"\""NS"QTextCodec\","
"\""NS"QVariant\","
"\""NS"QVector\","
"\""NS"QWeakPointer\","
"\""NS"QWidget\","
#ifdef Q_OS_WIN
"\"basic_string\","
@@ -2685,7 +2728,25 @@ void *qDumpObjectData440(
"\"" << ((QT_VERSION >> 16) & 255) << "\","
"\"" << ((QT_VERSION >> 8) & 255) << "\","
"\"" << ((QT_VERSION) & 255) << "\"]";
d << ",namespace=\""NS"\"";
d << ",namespace=\""NS"\",";
// Dump out size information
d << "sizes={";
d << "int=\"" << sizeof(int) << "\","
<< "char*=\"" << sizeof(char*) << "\","
<< ""NS"QString=\"" << sizeof(QString) << "\","
<< ""NS"QStringList=\"" << sizeof(QStringList) << "\","
<< ""NS"QObject=\"" << sizeof(QObject) << "\","
#ifdef QT_GUI_LIB
<< ""NS"QWidget=\"" << sizeof(QWidget)<< "\","
#endif
#ifdef Q_OS_WIN
<< "string=\"" << sizeof(std::string) << "\","
<< "wstring=\"" << sizeof(std::wstring) << "\","
#endif
<< "std::string=\"" << sizeof(std::string) << "\","
<< "std::wstring=\"" << sizeof(std::wstring) << "\","
<< "std::allocator=\"" << sizeof(std::allocator<int>)
<< "\"}";
d.disarm();
}

View File

@@ -0,0 +1,131 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qstringbuilder.h"
/*!
\class QLatin1Literal
\reentrant
\brief The QLatin1Literal class provides a thin wrapper of string literal
used in source codes.
The main use of \c QLatin1Literal is in conjunction with \c QStringBuilder
to reduce the number of reallocations needed to build up a string from
smaller chunks.
Contrary to \c QLatin1String, a \c QLatin1Literal can retrieve its size
int \i{O(1)}.
\ingroup tools
\ingroup shared
\ingroup text
\mainclass
\sa QStringBuilder, QLatin1String, QString
*/
/*! \fn QLatin1Literal::QLatin1Literal(const char(&literal)[])
The only constructor of the class.
*/
/*! \fn int QLatin1Literal::size() const
Returns the number of characters in the literal \i{not} including
the trailing NUL char.
*/
/*! \fn char *QLatin1Literal::size() const
Returns a pointer to the first character of the string literal.
The string literal is terminated by a NUL character.
*/
/*! \fn QLatin1Literal::operator QString() const
Converts the \c QLatin1Literal into a \c QString object.
*/
/*!
\class QStringBuilderPair
\reentrant
\brief QStringBuilderPair is a helper class template for building
QStringBuilder objects wrapping two smaller QStringBuilder object.
*/
/*!
\class QStringBuilder
\reentrant
\brief QStringBuilder is a template class providing a facility to build
up QStrings from smaller chunks.
\ingroup tools
\ingroup shared
\ingroup text
\mainclass
When creating strings from smaller chunks, typically \c QString::operator+()
is used, resulting \i{n - 1} reallocations when operating on \i{n} chunks.
QStringBuilder uses expression
templates to collect the individual parts, compute the total size,
allocate memory for the resulting QString object, and copy the contents
of the chunks into the result.
Using \c QStringBuilder::operator%() yield generally better performance then
using \c QString::operator+() on the same chunks if there are three or
more of them, and equal performance otherwise.
\sa QLatin1Literal, QString
*/
/* !fn template <class A, class B> QStringBuilder< QStringBuilderPair<A, B> > operator%(const A &a, const B &b)
Creates a helper object containing both parameters.
This is the main function to build up
*/

View File

@@ -0,0 +1,206 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSTRINGBUILDER_H
#define QSTRINGBUILDER_H
#include <QtCore/qstring.h>
#include <string.h>
class QLatin1Literal
{
public:
template <int N>
QLatin1Literal(const char (&str)[N]) : m_size(N - 1), m_data(str) {}
int size() const { return m_size; }
const char *data() const { return m_data; }
void append(QChar *&out) const
{
const char *s = m_data;
for (int i = m_size; --i >= 0;)
*out++ = *s++;
}
operator QString() const
{
QString s;
s.resize(m_size);
QChar *d = s.data();
append(d);
return s;
}
private:
const int m_size;
const char *m_data;
};
template <class A>
class QStringBuilder : public A
{
public:
QStringBuilder(A a_) : A(a_) {}
operator QString() const
{
QString s;
s.resize(this->size());
QChar *d = s.data();
this->append(d);
return s;
}
};
template <>
class QStringBuilder<QString>
{
public:
QStringBuilder(const QString &a_) : a(&a_) {}
inline int size() const { return a->size(); }
inline void append(QChar *&out) const
{
const int n = a->size();
memcpy(out, (char*)a->constData(), sizeof(QChar) * n);
out += n;
}
inline operator QString() const { return *a; }
private:
const QString *a;
};
template <>
class QStringBuilder<char>
{
public:
QStringBuilder(char c_) : c(c_) {}
inline int size() const { return 1; }
inline void append(QChar *&out) const { *out++ = QLatin1Char(c); }
private:
const char c;
};
template <class A, class B>
class QStringBuilderPair
{
public:
QStringBuilderPair(A a_, B b_) : a(a_), b(b_) {}
inline int size() const { return a.size() + b.size(); }
inline void append(QChar *&out) const { a.append(out); b.append(out); }
private:
A a;
B b;
};
template <class A, class B>
QStringBuilder< QStringBuilderPair<A, B> >
operator%(const A &a, const B &b)
{
return QStringBuilderPair<A, B> (a, b);
}
// QString related specializations
template <class A>
inline QStringBuilder< QStringBuilderPair<A, QStringBuilder<QString> > >
operator%(const A &a, const QString &b)
{
return QStringBuilderPair<A, QStringBuilder<QString> > (a, b);
}
template <class B>
inline QStringBuilder< QStringBuilderPair<QStringBuilder<QString>, B> >
operator%(const QString &a, const B &b)
{
return QStringBuilderPair<QStringBuilder<QString>, B> (a, b);
}
inline QStringBuilder<
QStringBuilderPair<QStringBuilder<QString>, QStringBuilder<QString> >
>
operator%(const QString &a, const QString &b)
{
return QStringBuilderPair< QStringBuilder<QString>,
QStringBuilder<QString> > (a, b);
}
// char related specializations
template <class A>
inline QStringBuilder< QStringBuilderPair<A, QStringBuilder<char> > >
operator%(const A &a, char b)
{
return QStringBuilderPair<A, QStringBuilder<char> > (a, b);
}
template <class B>
inline QStringBuilder< QStringBuilderPair<QStringBuilder<char>, B> >
operator%(char a, const B &b)
{
return QStringBuilderPair<QStringBuilder<QString>, B> (a, b);
}
inline QStringBuilder<
QStringBuilderPair<QStringBuilder<QString>, QStringBuilder<char> >
>
operator%(const QString &a, char b)
{
return QStringBuilderPair<
QStringBuilder<QString>, QStringBuilder<char>
> (a, b);
}
#endif // QSTRINGBUILDER_H

View File

@@ -181,7 +181,6 @@ void CdbDumperHelper::reset(const QString &library, bool enabled)
m_helper.clear();
m_inBufferAddress = m_outBufferAddress = 0;
m_inBufferSize = m_outBufferSize = 0;
m_typeSizeCache.clear();
m_failedTypes.clear();
clearBuffer();
}
@@ -405,7 +404,9 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool
// Check failure cache and supported types
if (m_failedTypes.contains(wd.type))
return DumpNotHandled;
const QtDumperHelper::TypeData td = m_helper.typeData(wd.type);
const QtDumperHelper::TypeData td = m_helper.typeData(wd.type);
if (loadDebug)
qDebug() << wd.type << td;
if (td.type == QtDumperHelper::UnknownType)
return DumpNotHandled;
@@ -448,10 +449,11 @@ CdbDumperHelper::DumpExecuteResult
int size;
ep.truncate(ep.lastIndexOf(QLatin1Char(')')));
ep.remove(0, ep.indexOf(QLatin1Char('(')) + 1);
if (!getTypeSize(ep, &size, errorMessage))
return DumpExecuteSizeFailed;
const bool sizeOk = getTypeSize(ep, &size, errorMessage);
if (loadDebug)
qDebug() << "Size" << size << ep;
qDebug() << "Size" << sizeOk << size << ep;
if (!sizeOk)
return DumpExecuteSizeFailed;
ep = QString::number(size);
}
}
@@ -461,7 +463,7 @@ CdbDumperHelper::DumpExecuteResult
<< "(2,0," << wd.addr << ','
<< (dumpChildren ? 1 : 0) << ',' << extraParameters.join(QString(QLatin1Char(','))) << ')';
if (loadDebug)
qDebug() << "Query: " << wd.toString() << "\nwith: " << callCmd;
qDebug() << "Query: " << wd.toString() << "\nwith: " << callCmd << '\n';
const char *outputData;
if (!callDumper(callCmd, inBuffer, &outputData, errorMessage))
return DumpExecuteCallFailed;
@@ -486,11 +488,6 @@ bool CdbDumperHelper::getTypeSize(const QString &typeNameIn, int *size, QString
if (loadDebug > 1)
qDebug() << Q_FUNC_INFO << typeNameIn;
// Look up cache
const TypeSizeCache::const_iterator it = m_typeSizeCache.constFind(typeNameIn);
if (it != m_typeSizeCache.constEnd()) {
*size = it.value();
return true;
}
QString typeName = typeNameIn;
simplifySizeExpression(&typeName);
// "std::" types sometimes only work without namespace.
@@ -511,8 +508,9 @@ bool CdbDumperHelper::getTypeSize(const QString &typeNameIn, int *size, QString
break;
success = true;
} while (false);
// Cache in dumper helper
if (success)
m_typeSizeCache.insert(typeName, *size);
m_helper.addSize(typeName, *size);
return success;
}

View File

@@ -119,8 +119,6 @@ private:
unsigned long m_outBufferSize;
char *m_buffer;
typedef QMap<QString, int> TypeSizeCache;
TypeSizeCache m_typeSizeCache;
QStringList m_failedTypes;
QtDumperHelper m_helper;

View File

@@ -3047,11 +3047,10 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
//int protocol = isDisplayedIName(data.iname) ? 3 : 2;
QString addr;
if (data.addr.startsWith(QLatin1String("0x"))) {
if (data.addr.startsWith(QLatin1String("0x")))
addr = QLatin1String("(void*)") + data.addr;
} else {
else
addr = QLatin1String("&(") + data.exp + QLatin1Char(')');
}
sendWatchParameters(params);
@@ -3061,8 +3060,6 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
<<',' << addr << ',' << (dumpChildren ? "1" : "0")
<< ',' << extraArgs.join(QString(QLatin1Char(','))) << ')';
qDebug() << "CMD: " << cmd;
QVariant var;
var.setValue(data);
sendSynchronizedCommand(cmd, WatchDebuggingHelperValue1, var);
@@ -3344,7 +3341,7 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record)
q->showStatusMessage(tr("%1 custom dumpers found.")
.arg(m_dumperHelper.typeCount()));
}
qDebug() << m_dumperHelper.toString(true);
//qDebug() << m_dumperHelper.toString(true);
//qDebug() << "DATA DUMPERS AVAILABLE" << m_availableSimpleDebuggingHelpers;
}

View File

@@ -38,6 +38,7 @@
#include "registerhandler.h"
#include "stackhandler.h"
#include "watchhandler.h"
#include "watchutils.h"
#include "moduleshandler.h"
#include <utils/qtcassert.h>
@@ -422,28 +423,6 @@ static WatchData m_toolTip;
static QPoint m_toolTipPos;
static QHash<QString, WatchData> m_toolTipCache;
static bool hasLetterOrNumber(const QString &exp)
{
for (int i = exp.size(); --i >= 0; )
if (exp[i].isLetterOrNumber())
return true;
return false;
}
static bool hasSideEffects(const QString &exp)
{
// FIXME: complete?
return exp.contains("-=")
|| exp.contains("+=")
|| exp.contains("/=")
|| exp.contains("*=")
|| exp.contains("&=")
|| exp.contains("|=")
|| exp.contains("^=")
|| exp.contains("--")
|| exp.contains("++");
}
void ScriptEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
{
Q_UNUSED(pos);

View File

@@ -166,8 +166,10 @@ bool isPointerType(const QString &type)
bool isAccessSpecifier(const QString &str)
{
static const QStringList items =
QStringList() << QLatin1String("private") << QLatin1String("protected") << QLatin1String("public");
static const QStringList items = QStringList()
<< QLatin1String("private")
<< QLatin1String("protected")
<< QLatin1String("public");
return items.contains(str);
}
@@ -326,28 +328,28 @@ static QString quoteUnprintableLatin1(const QByteArray &ba)
return res;
}
QString decodeData(const QByteArray &baIn, int encoding)
QString decodeData(const QByteArray &ba, int encoding)
{
switch (encoding) {
case 0: // unencoded 8 bit data
return quoteUnprintableLatin1(baIn);
return quoteUnprintableLatin1(ba);
case 1: { // base64 encoded 8 bit data, used for QByteArray
const QChar doubleQuote(QLatin1Char('"'));
QString rc = doubleQuote;
rc += quoteUnprintableLatin1(QByteArray::fromBase64(baIn));
rc += quoteUnprintableLatin1(QByteArray::fromBase64(ba));
rc += doubleQuote;
return rc;
}
case 2: { // base64 encoded 16 bit data, used for QString
const QChar doubleQuote(QLatin1Char('"'));
const QByteArray ba = QByteArray::fromBase64(baIn);
const QByteArray ba = QByteArray::fromBase64(ba);
QString rc = doubleQuote;
rc += QString::fromUtf16(reinterpret_cast<const ushort *>(ba.data()), ba.size() / 2);
rc += doubleQuote;
return rc;
}
case 3: { // base64 encoded 32 bit data
const QByteArray ba = QByteArray::fromBase64(baIn);
const QByteArray ba = QByteArray::fromBase64(ba);
const QChar doubleQuote(QLatin1Char('"'));
QString rc = doubleQuote;
rc += QString::fromUcs4(reinterpret_cast<const uint *>(ba.data()), ba.size() / 4);
@@ -355,7 +357,7 @@ QString decodeData(const QByteArray &baIn, int encoding)
return rc;
}
case 4: { // base64 encoded 16 bit data, without quotes (see 2)
const QByteArray ba = QByteArray::fromBase64(baIn);
const QByteArray ba = QByteArray::fromBase64(ba);
return QString::fromUtf16(reinterpret_cast<const ushort *>(ba.data()), ba.size() / 2);
}
}
@@ -374,7 +376,6 @@ QtDumperResult::QtDumperResult() :
valuedisabled(false),
childCount(0),
internal(false)
{
}
@@ -470,6 +471,10 @@ void QtDumperHelper::TypeData::clear()
// ----------------- QtDumperHelper
QtDumperHelper::QtDumperHelper() :
m_stdAllocatorPrefix(QLatin1String("std::allocator")),
m_intSize(0),
m_pointerSize(0),
m_stdAllocatorSize(0),
m_qtVersion(0)
{
}
@@ -479,6 +484,10 @@ void QtDumperHelper::clear()
m_nameTypeMap.clear();
m_qtVersion = 0;
m_qtNamespace.clear();
m_sizeCache.clear();
m_intSize = 0;
m_pointerSize = 0;
m_stdAllocatorSize = 0;
}
static inline void formatQtVersion(int v, QTextStream &str)
@@ -498,6 +507,12 @@ QString QtDumperHelper::toString(bool debug) const
for (NameTypeMap::const_iterator it = m_nameTypeMap.constBegin(); it != cend; ++it) {
str <<",[" << it.key() << ',' << it.value() << ']';
}
str << "Sizes: intsize=" << m_intSize << " pointer size=" << m_pointerSize
<< " allocatorsize=" << m_stdAllocatorSize;
const SizeCache::const_iterator scend = m_sizeCache.constEnd();
for (SizeCache::const_iterator it = m_sizeCache.constBegin(); it != scend; ++it) {
str << ' ' << it.key() << '=' << it.value();
}
return rc;
}
const QString nameSpace = m_qtNamespace.isEmpty() ? QCoreApplication::translate("QtDumperHelper", "<none>") : m_qtNamespace;
@@ -584,7 +599,6 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
return UnknownType;
}
bool QtDumperHelper::needsExpressionSyntax(Type t)
{
switch (t) {
@@ -600,7 +614,7 @@ bool QtDumperHelper::needsExpressionSyntax(Type t)
return true;
default:
break;
}
}
return false;
}
@@ -638,9 +652,8 @@ void QtDumperHelper::parseQueryTypes(const QStringList &l, Debugger debugger)
const Type t = specialType(l.at(i));
if (t != UnknownType) {
// Exclude types that require expression syntax for CDB
if (debugger == GdbDebugger || !needsExpressionSyntax(t)) {
if (debugger == GdbDebugger || !needsExpressionSyntax(t))
m_nameTypeMap.insert(l.at(i), t);
}
} else {
m_nameTypeMap.insert(l.at(i), SupportedType);
}
@@ -654,7 +667,8 @@ void QtDumperHelper::parseQueryTypes(const QStringList &l, Debugger debugger)
* value="dABoAHIAZQBlAA==",valueencoded="2"}]"
* Default implementation can be used for debugging purposes. */
class DumperParser {
class DumperParser
{
public:
explicit DumperParser(const char *s) : m_s(s) {}
bool run();
@@ -824,6 +838,7 @@ bool DumperParser::handleValue(const char *k, int size)
class QueryDumperParser : public DumperParser {
public:
typedef QPair<QString, int> SizeEntry;
explicit QueryDumperParser(const char *s);
struct Data {
@@ -831,20 +846,23 @@ public:
QString qtNameSpace;
QString qtVersion;
QStringList types;
QList<SizeEntry> sizes;
};
inline Data data() const { return m_data; }
protected:
virtual bool handleKeyword(const char *k, int size);
virtual bool handleListStart();
virtual bool handleListStart();
virtual bool handleListEnd();
virtual bool handleHashEnd();
virtual bool handleValue(const char *k, int size);
private:
enum Mode { None, ExpectingDumpers, ExpectingVersion, ExpectingNameSpace };
enum Mode { None, ExpectingDumpers, ExpectingVersion, ExpectingNameSpace, ExpectingSizes };
Mode m_mode;
Data m_data;
QString m_lastSizeType;
};
QueryDumperParser::QueryDumperParser(const char *s) :
@@ -854,7 +872,11 @@ QueryDumperParser::QueryDumperParser(const char *s) :
}
bool QueryDumperParser::handleKeyword(const char *k, int size)
{
{
if (m_mode == ExpectingSizes) {
m_lastSizeType = QString::fromLatin1(k, size);
return true;
}
if (!qstrncmp(k, "dumpers", size)) {
m_mode = ExpectingDumpers;
return true;
@@ -867,6 +889,10 @@ bool QueryDumperParser::handleKeyword(const char *k, int size)
m_mode = ExpectingNameSpace;
return true;
}
if (!qstrncmp(k, "sizes", size)) {
m_mode = ExpectingSizes;
return true;
}
qWarning("%s Unexpected keyword %s.\n", Q_FUNC_INFO, QByteArray(k, size).constData());
return false;
}
@@ -882,15 +908,21 @@ bool QueryDumperParser::handleListEnd()
return true;
}
bool QueryDumperParser::handleHashEnd()
{
m_mode = None; // Size hash
return true;
}
bool QueryDumperParser::handleValue(const char *k, int size)
{
switch (m_mode) {
case None:
case None:
return false;
case ExpectingDumpers:
case ExpectingDumpers:
m_data.types.push_back(QString::fromLatin1(k, size));
break;
case ExpectingNameSpace:
case ExpectingNameSpace:
m_data.qtNameSpace = QString::fromLatin1(k, size);
break;
case ExpectingVersion: // ["4","1","5"]
@@ -898,6 +930,9 @@ bool QueryDumperParser::handleValue(const char *k, int size)
m_data.qtVersion += QLatin1Char('.');
m_data.qtVersion += QString::fromLatin1(k, size);
break;
case ExpectingSizes:
m_data.sizes.push_back(SizeEntry(m_lastSizeType, QString::fromLatin1(k, size).toInt()));
break;
}
return true;
}
@@ -905,7 +940,6 @@ bool QueryDumperParser::handleValue(const char *k, int size)
// parse a query
bool QtDumperHelper::parseQuery(const char *data, Debugger debugger)
{
QueryDumperParser parser(data);
if (!parser.run())
return false;
@@ -913,9 +947,39 @@ bool QtDumperHelper::parseQuery(const char *data, Debugger debugger)
m_qtNamespace = parser.data().qtNameSpace;
setQtVersion(parser.data().qtVersion);
parseQueryTypes(parser.data().types, debugger);
foreach (const QueryDumperParser::SizeEntry &se, parser.data().sizes)
addSize(se.first, se.second);
return true;
}
void QtDumperHelper::addSize(const QString &name, int size)
{
// Special interest cases
do {
if (name == QLatin1String("char*")) {
m_pointerSize = size;
break;
}
if (name == QLatin1String("int")) {
m_intSize = size;
break;
}
if (name.startsWith(m_stdAllocatorPrefix)) {
m_stdAllocatorSize = size;
break;
}
if (name == QLatin1String("std::string")) {
m_sizeCache.insert(QLatin1String("std::basic_string<char,std::char_traits<char>,std::allocator<char>>"), size);
break;
}
if (name == QLatin1String("std::wstring")) {
m_sizeCache.insert(QLatin1String("std::basic_string<unsigned short,std::char_traits<unsignedshort>,std::allocator<unsignedshort> >"), size);
break;
}
} while (false);
m_sizeCache.insert(name, size);
}
QtDumperHelper::Type QtDumperHelper::type(const QString &typeName) const
{
const QtDumperHelper::TypeData td = typeData(typeName);
@@ -941,9 +1005,26 @@ QtDumperHelper::TypeData QtDumperHelper::typeData(const QString &typeName) const
return td;
}
// Format an expression to have the debugger query the
// size. Use size cache if possible
QString QtDumperHelper::evaluationSizeofTypeExpression(const QString &typeName,
Debugger /* debugger */) const
{
// Look up fixed types
if (m_pointerSize && isPointerType(typeName))
return QString::number(m_pointerSize);
if (m_stdAllocatorSize && typeName.startsWith(m_stdAllocatorPrefix))
return QString::number(m_stdAllocatorSize);
const SizeCache::const_iterator sit = m_sizeCache.constFind(typeName);
if (sit != m_sizeCache.constEnd())
return QString::number(sit.value());
// Finally have the debugger evaluate
return sizeofTypeExpression(typeName);
}
void QtDumperHelper::evaluationParameters(const WatchData &data,
const TypeData &td,
Debugger /* debugger */,
Debugger debugger,
QByteArray *inBuffer,
QStringList *extraArgsIn) const
{
@@ -970,7 +1051,7 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
// gives already most information the dumpers need
const int count = qMin(int(maxExtraArgCount), inners.size());
for (int i = 0; i < count; i++)
extraArgs.push_back(sizeofTypeExpression(inners.at(i)));
extraArgs.push_back(evaluationSizeofTypeExpression(inners.at(i), debugger));
}
int extraArgCount = extraArgs.size();
// Pad with zeros
@@ -1019,14 +1100,14 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
}
//qDebug() << "OUTERTYPE: " << outertype << " NODETYPE: " << nodetype
// << "QT VERSION" << m_qtVersion << ((4 << 16) + (5 << 8) + 0);
extraArgs[2] = sizeofTypeExpression(nodetype);
extraArgs[2] = evaluationSizeofTypeExpression(nodetype, debugger);
extraArgs[3] = QLatin1String("(size_t)&(('");
extraArgs[3] += nodetype;
extraArgs[3] += QLatin1String("'*)0)->value");
}
break;
case QMapNodeType:
extraArgs[2] = sizeofTypeExpression(data.type);
extraArgs[2] = evaluationSizeofTypeExpression(data.type, debugger);
extraArgs[3] = QLatin1String("(size_t)&(('");
extraArgs[3] += data.type;
extraArgs[3] += QLatin1String("'*)0)->value");
@@ -1036,7 +1117,7 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
if (inners.at(0) == QLatin1String("bool")) {
outertype = QLatin1String("std::vector::bool");
} else {
//extraArgs[extraArgCount++] = sizeofTypeExpression(data.type);
//extraArgs[extraArgCount++] = evaluationSizeofTypeExpression(data.type, debugger);
//extraArgs[extraArgCount++] = "(size_t)&(('" + data.type + "'*)0)->value";
}
break;
@@ -1101,11 +1182,13 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
/* Parse value:
* "iname="local.sl",addr="0x0012BA84",value="<3 items>",valuedisabled="true",
* numchild="3",childtype="QString",childnumchild="0",children=[{name="0",value="<binhex>",
* valueencoded="2"},{name="1",value="dAB3AG8A",valueencoded="2"},{name="2",
* value="dABoAHIAZQBlAA==",valueencoded="2"}]" */
* numchild="3",childtype="QString",childnumchild="0",
* children=[{name="0",value="<binhex>",valueencoded="2"},
* {name="1",value="dAB3AG8A",valueencoded="2"},
* {name="2",value="dABoAHIAZQBlAA==",valueencoded="2"}]" */
class ValueDumperParser : public DumperParser {
class ValueDumperParser : public DumperParser
{
public:
explicit ValueDumperParser(const char *s);
@@ -1260,5 +1343,14 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r)
return true;
}
QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d)
{
QDebug nsp = in.nospace();
nsp << " type=" << d.type << " tpl=" << d.isTemplate;
if (d.isTemplate)
nsp << d.tmplate << '<' << d.inner << '>';
return in;
}
}
}

View File

@@ -114,7 +114,8 @@ QDebug operator<<(QDebug in, const QtDumperResult &d);
* 2) Evaluate symbol, taking address and some additional parameters
* depending on type. */
class QtDumperHelper {
class QtDumperHelper
{
public:
enum Debugger {
GdbDebugger, // Can evalulate expressions in function calls
@@ -127,7 +128,7 @@ public:
// Below types require special handling
QObjectType, QWidgetType, QObjectSlotType, QObjectSignalType,
QVectorType, QMapType, QMultiMapType, QMapNodeType,
StdVectorType, StdDequeType, StdSetType,StdMapType, StdStackType,
StdVectorType, StdDequeType, StdSetType, StdMapType, StdStackType,
StdStringType
};
@@ -181,17 +182,29 @@ public:
QString toString(bool debug = false) const;
private:
void addSize(const QString &name, int size);
private:
typedef QMap<QString, Type> NameTypeMap;
typedef QMap<QString, int> SizeCache;
// Look up a simple (namespace) type
static Type specialType(QString s);
QString evaluationSizeofTypeExpression(const QString &typeName, Debugger d) const;
const QString m_stdAllocatorPrefix;
NameTypeMap m_nameTypeMap;
SizeCache m_sizeCache;
int m_intSize;
int m_pointerSize;
int m_stdAllocatorSize;
int m_qtVersion;
QString m_qtNamespace;
};
QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d);
} // namespace Internal
} // namespace Debugger

View File

@@ -1499,7 +1499,7 @@ QRect BaseTextEditor::collapseBox()
QTextBlock begin = document()->findBlockByNumber(d->m_highlightBlocksInfo.open.last());
if (!d->m_displaySettings.m_fancyFoldingBar) {
if (true || !d->m_displaySettings.m_fancyFoldingBar) {
if (TextBlockUserData::hasCollapseAfter(begin.previous()))
begin = begin.previous();
}
@@ -2231,23 +2231,6 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top();
int bottom = top;
#if 0
int extraAreaHighlightCollapseEndBlockNumber = -1;
int extraAreaHighlightCollapseBlockNumber = d->extraAreaHighlightCollapseBlockNumber;
if (extraAreaHighlightCollapseBlockNumber < 0) {
extraAreaHighlightCollapseBlockNumber = d->extraAreaHighlightFadingBlockNumber;
}
if (extraAreaHighlightCollapseBlockNumber >= 0 ) {
QTextBlock highlightBlock = doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber);
if (highlightBlock.isValid() && highlightBlock.next().isValid() && highlightBlock.next().isVisible())
extraAreaHighlightCollapseEndBlockNumber = TextBlockUserData::testCollapse(highlightBlock).blockNumber();
else
extraAreaHighlightCollapseEndBlockNumber = extraAreaHighlightCollapseBlockNumber;
}
#endif
while (block.isValid() && top <= e->rect().bottom()) {
top = bottom;
@@ -2304,20 +2287,29 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
QRect r(extraAreaWidth+2, top, collapseBoxWidth-4, bottom - top);
bool drawBox = !nextBlock.isVisible();
int minBraceDepth = qMax(braceDepth, previousBraceDepth);
if (minBraceDepth > 0) {
QColor color = calcBlendColor(baseColor, minBraceDepth);
if (!d->m_highlightBlocksInfo.isEmpty()
&& blockNumber >= d->m_highlightBlocksInfo.open.last()
&& blockNumber <= d->m_highlightBlocksInfo.close.first())
color = calcMixColor(pal.highlight().color(), color);
painter.fillRect(r, color);
int extraAreaHighlightCollapseBlockNumber = -1;
int extraAreaHighlightCollapseEndBlockNumber = -1;
if (!d->m_highlightBlocksInfo.isEmpty()) {
extraAreaHighlightCollapseBlockNumber = d->m_highlightBlocksInfo.open.last();
extraAreaHighlightCollapseEndBlockNumber = d->m_highlightBlocksInfo.close.first();
QTextBlock before = doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber-1);
if (TextBlockUserData::hasCollapseAfter(before)) {
extraAreaHighlightCollapseBlockNumber--;
}
}
int minBraceDepth = qMax(braceDepth, previousBraceDepth);
QColor color = calcBlendColor(baseColor, minBraceDepth);
if (!d->m_highlightBlocksInfo.isEmpty()
&& blockNumber >= extraAreaHighlightCollapseBlockNumber
&& blockNumber <= extraAreaHighlightCollapseEndBlockNumber)
color = calcMixColor(pal.highlight().color(), color);
painter.fillRect(r, color);
bool drawDown = !d->m_highlightBlocksInfo.isEmpty()
&& blockNumber == d->m_highlightBlocksInfo.open.last();
&& blockNumber == extraAreaHighlightCollapseBlockNumber;
bool drawUp = !d->m_highlightBlocksInfo.isEmpty()
&& blockNumber == d->m_highlightBlocksInfo.close.first();
&& blockNumber == extraAreaHighlightCollapseEndBlockNumber;
if (drawBox || drawDown || drawUp) {
painter.setRenderHint(QPainter::Antialiasing, true);
@@ -2337,7 +2329,7 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
} else if (drawUp) {
// check that we are not collapsed
QTextBlock open = doc->findBlockByNumber(d->m_highlightBlocksInfo.open.last());
QTextBlock open = doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber);
if (open.next().isVisible()) {
QPointF points[3] = { QPointF(r.left(), r.bottom()-1),
@@ -2347,8 +2339,8 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
}
} else if(drawDown) {
QPointF points[3] = { QPointF(r.left(), r.top()),
QPointF(r.center().x(), r.center().y()),
QPointF(r.right(), r.top()) };
QPointF(r.center().x(), r.center().y()),
QPointF(r.right(), r.top()) };
painter.drawPolygon(points, 3);
}
painter.translate(-.5, -.5);
@@ -2378,8 +2370,8 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
extraAreaHighlightCollapseEndBlockNumber = d->m_highlightBlocksInfo.close.first();
endIsVisible = doc->findBlockByNumber(extraAreaHighlightCollapseEndBlockNumber).isVisible();
if (TextBlockUserData::hasCollapseAfter(
doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber-1))) {
QTextBlock before = doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber-1);
if (TextBlockUserData::hasCollapseAfter(before)) {
extraAreaHighlightCollapseBlockNumber--;
}
}
@@ -2698,12 +2690,15 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
int collapseBoxWidth = fontMetrics().lineSpacing() + 1;
if (e->pos().x() > extraArea()->width() - collapseBoxWidth) {
d->extraAreaHighlightCollapseBlockNumber = cursor.blockNumber();
if (!TextBlockUserData::hasClosingCollapse(cursor.block()))
if (TextBlockUserData::canCollapse(cursor.block())
|| !TextBlockUserData::hasClosingCollapse(cursor.block()))
d->extraAreaHighlightCollapseColumn = cursor.block().length()-1;
if (!d->m_displaySettings.m_fancyFoldingBar
if ((true || !d->m_displaySettings.m_fancyFoldingBar)
&& TextBlockUserData::hasCollapseAfter(cursor.block())) {
d->extraAreaHighlightCollapseBlockNumber++;
if (!TextBlockUserData::hasClosingCollapse(cursor.block().next()))
d->extraAreaHighlightCollapseColumn = -1;
if (TextBlockUserData::canCollapse(cursor.block().next())
|| !TextBlockUserData::hasClosingCollapse(cursor.block().next()))
d->extraAreaHighlightCollapseColumn = cursor.block().next().length()-1;
}
}
@@ -3299,8 +3294,9 @@ bool TextBlockUserData::findPreviousBlockOpenParenthesis(QTextCursor *cursor, bo
if (block == cursor->block()) {
if (position - block.position() <= paren.pos + (paren.type == Parenthesis::Closed ? 1 : 0))
continue;
if (checkStartPosition && paren.type == Parenthesis::Opened && position == cursor->position())
if (checkStartPosition && paren.type == Parenthesis::Opened && paren.pos== cursor->position()) {
return true;
}
}
if (paren.type == Parenthesis::Closed) {
++ignore;
@@ -3820,6 +3816,10 @@ void BaseTextEditor::setDisplaySettings(const DisplaySettings &ds)
}
d->m_displaySettings = ds;
d->extraAreaHighlightCollapseBlockNumber = d->extraAreaHighlightCollapseColumn = -1;
d->m_highlightBlocksInfo = BaseTextEditorPrivateHighlightBlocks();
viewport()->update();
extraArea()->update();
}
void BaseTextEditor::setStorageSettings(const StorageSettings &storageSettings)

View File

@@ -143,10 +143,12 @@ public:
inline static bool hasCollapseAfter(const QTextBlock & block)
{
if (!block.isValid())
return false;
TextBlockUserData *data = static_cast<TextBlockUserData*>(block.userData());
if (data && data->collapseMode() != NoCollapse) {
return (data->collapseMode() == CollapseAfter);
} else if (!data) {
return false;
} else if (block.next().isValid()) {
data = static_cast<TextBlockUserData*>(block.next().userData());
if (data && data->collapseMode() == TextBlockUserData::CollapseThis && !data->m_ifdefedOut)
return true;

View File

@@ -61,8 +61,13 @@ void BaseTextMark::init()
void BaseTextMark::editorOpened(Core::IEditor *editor)
{
#ifdef Q_OS_WIN
if (m_fileName.compare(editor->file()->fileName(), Qt::CaseInsensitive))
return;
#else
if (editor->file()->fileName() != m_fileName)
return;
#endif
if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) {
if (m_markableInterface == 0) { // We aren't added to something
m_markableInterface = textEditor->markableInterface();

View File

@@ -0,0 +1,11 @@
load(qttest_p4)
SOURCES += tst_qstringbuilder.cpp
QT -= gui
QT = core
DEFINES += QT_NO_CAST_TO_ASCII

View File

@@ -0,0 +1,48 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
****************************************************************************/
#include <QtTest/QtTest>
#include "../../../src/libs/utils/qstringbuilder.h"
//TESTED_CLASS=QStringBuilder
//TESTED_FILES=qstringbuilder.h
class tst_QStringBuilder : public QObject
{
Q_OBJECT
public:
tst_QStringBuilder();
~tst_QStringBuilder() {}
public slots:
void init() {}
void cleanup() {}
private slots:
void operator_percent();
};
tst_QStringBuilder::tst_QStringBuilder()
{
//QTextCodec::setCodecForLocale(QTextCodec::codecForName("ISO 8859-1"));
}
void tst_QStringBuilder::operator_percent()
{
QLatin1Literal l1literal("a literal");
QLatin1String l1string("a literal");
QLatin1Char l1char('c');
QChar qchar(l1char);
QCOMPARE(QString(l1literal % l1literal), QString(l1string + l1string));
}
QTEST_APPLESS_MAIN(tst_QStringBuilder)
#include "tst_qstringbuilder.moc"

View File

@@ -0,0 +1,106 @@
#include <QDebug>
#include <QString>
#include "../../../src/libs/utils/qstringbuilder.h"
#include <qtest.h>
class tst_qstringbuilder : public QObject
{
Q_OBJECT
public:
tst_qstringbuilder();
private slots:
// QStringBuilder based
void b_separator() { qDebug() << "\n------- QStringBuilder based ----------"; }
void b_2_l1literal();
void b_3_l1literal();
void b_4_l1literal();
void b_string_4_char();
// QString based for comparison
void s_separator() { qDebug() << "\n-------- QString based ---------"; }
void s_2_l1string();
void s_3_l1string();
void s_4_l1string();
void s_string_4_char();
private:
const QLatin1Literal l1literal;
const QLatin1String l1string;
const QString string;
const char achar;
};
tst_qstringbuilder::tst_qstringbuilder()
: l1literal("some literal"),
l1string("some literal"),
string(l1string),
achar('c')
{}
void tst_qstringbuilder::b_2_l1literal()
{
QString result;
QBENCHMARK { result = l1literal % l1literal; }
QCOMPARE(result, l1string + l1string);
}
void tst_qstringbuilder::b_3_l1literal()
{
QString result;
QBENCHMARK { result = l1literal % l1literal % l1literal; }
QCOMPARE(result, l1string + l1string + l1string);
}
void tst_qstringbuilder::b_4_l1literal()
{
QString result;
QBENCHMARK { result = l1literal % l1literal % l1literal % l1literal; }
QCOMPARE(result, l1string + l1string + l1string + l1string);
}
void tst_qstringbuilder::b_string_4_char()
{
QString result;
QBENCHMARK { result = string + achar + achar + achar; }
QCOMPARE(result, QString(string % achar % achar % achar));
}
void tst_qstringbuilder::s_2_l1string()
{
QString result;
QBENCHMARK { result = l1string + l1string; }
QCOMPARE(result, QString(l1literal % l1literal));
}
void tst_qstringbuilder::s_3_l1string()
{
QString result;
QBENCHMARK { result = l1string + l1string + l1string; }
QCOMPARE(result, QString(l1literal % l1literal % l1literal));
}
void tst_qstringbuilder::s_4_l1string()
{
QString result;
QBENCHMARK { result = l1string + l1string + l1string + l1string; }
QCOMPARE(result, QString(l1literal % l1literal % l1literal % l1literal));
}
void tst_qstringbuilder::s_string_4_char()
{
QString result;
QBENCHMARK { result = string + achar + achar + achar; }
QCOMPARE(result, QString(string % achar % achar % achar));
}
QTEST_MAIN(tst_qstringbuilder)
#include "main.moc"

View File

@@ -0,0 +1,12 @@
load(qttest_p4)
TEMPLATE = app
TARGET = tst_qstringbuilder
DEPENDPATH += .
INCLUDEPATH += .
QT -= gui
CONFIG += release
# Input
SOURCES += main.cpp

View File

@@ -549,9 +549,13 @@ void testQSharedPointer()
QSharedPointer<QString> ptr2 = ptr;
QSharedPointer<QString> ptr3 = ptr;
//QWeakPointer<QString> wptr(ptr);
//QWeakPointer<QString> wptr2 = wptr;
//QWeakPointer<QString> wptr3 = wptr;
QWeakPointer<int> wiptr(iptr);
QWeakPointer<int> wiptr2 = wiptr;
QWeakPointer<int> wiptr3 = wiptr;
QWeakPointer<QString> wptr(ptr);
QWeakPointer<QString> wptr2 = wptr;
QWeakPointer<QString> wptr3 = wptr;
}
void stringRefTest(const QString &refstring)