forked from qt-creator/qt-creator
Merge branch 'master' of ../mainline into dui-editor
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
131
src/libs/utils/qstringbuilder.cpp
Normal file
131
src/libs/utils/qstringbuilder.cpp
Normal 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
|
||||
*/
|
||||
206
src/libs/utils/qstringbuilder.h
Normal file
206
src/libs/utils/qstringbuilder.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
11
tests/auto/qstringbuilder/qstringbuilder.pro
Normal file
11
tests/auto/qstringbuilder/qstringbuilder.pro
Normal file
@@ -0,0 +1,11 @@
|
||||
load(qttest_p4)
|
||||
SOURCES += tst_qstringbuilder.cpp
|
||||
|
||||
QT -= gui
|
||||
|
||||
QT = core
|
||||
|
||||
DEFINES += QT_NO_CAST_TO_ASCII
|
||||
|
||||
|
||||
|
||||
48
tests/auto/qstringbuilder/tst_qstringbuilder.cpp
Normal file
48
tests/auto/qstringbuilder/tst_qstringbuilder.cpp
Normal 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"
|
||||
106
tests/benchmarks/qstringbuilder/main.cpp
Normal file
106
tests/benchmarks/qstringbuilder/main.cpp
Normal 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"
|
||||
12
tests/benchmarks/qstringbuilder/qstringbuilder.pro
Normal file
12
tests/benchmarks/qstringbuilder/qstringbuilder.pro
Normal file
@@ -0,0 +1,12 @@
|
||||
load(qttest_p4)
|
||||
TEMPLATE = app
|
||||
TARGET = tst_qstringbuilder
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
QT -= gui
|
||||
|
||||
CONFIG += release
|
||||
|
||||
# Input
|
||||
SOURCES += main.cpp
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user