Merge remote-tracking branch 'origin/2.6'

Conflicts:
	src/plugins/remotelinux/deploymentinfo.cpp

Change-Id: I92af9f9f558a76db78f838b0ccdfb8ad3d47af25
This commit is contained in:
Oswald Buddenhagen
2012-08-28 15:13:32 +02:00
40 changed files with 350 additions and 200 deletions

View File

@@ -32,24 +32,21 @@
\title Setting Up Debugger
The main debugger settings are associated with the \l{glossary-tool-chain}
{tool chains} used to build your project.
To configure tool chains, select \gui{Tools > Options > Build and Run >
Tool Chains}. The view lists the tool chains that \QC detected
automatically. You can add tool chains.
The main debugger settings are associated with the build
\l{glossary-development-target}{target} of your project. To specify the
debugger and compiler to use for each build target, select \gui Tools >
\gui Options > \gui {Build and Run} > \gui Targets.
You need to set up the debugger only if the automatic setup
fails, because the native debugger is missing (as is usually the
case for the CDB debugger on Windows, which you always must install
yourself) or because the installed version is not supported (e.g.
yourself) or because the installed version is not supported (for example,
when your system contains no, or an outdated version of GDB and you
want to use a locally installed replacement instead).
\note If you need to change parameters of an automatically detected
toolchain, you can \gui{Clone} the tool chain and change the
parameters in the clone. Make sure to select the cloned tool chain
in the build settings of your project.
\note If you need to change the debugger to use for an automatically
detected target, you can \gui{Clone} the target and change the parameters in
the clone. Make sure to select the cloned target for your project.
\note To use the debugging tools for Windows, you must install them
and add the Symbol Server provided by Microsoft to the symbol search
@@ -57,7 +54,7 @@
Server in Windows}.
\note To use the Free Software Foundation (FSF) version of GDB on
Mac OS, you must sign it and modify your tool chain settings.
Mac OS, you must sign it and modify your target settings.
This section explains the options you have for debugging C++ code
and provides installation notes for the supported native debuggers.
@@ -237,7 +234,7 @@
supports Python from
\l{ftp://ftp.qt.nokia.com/misc/gdb/7.2/gdb72_mac_platform.tar.bz2}.
To use FSF GDB on Mac OS, you must sign it and add it to the \QC
tool chains. For more information, see
targets. For more information, see
\l{Setting up FSF GDB for Mac OS}.
\note The Mac OS X Snow Leopard (10.6) has a bug that might cause the
@@ -275,8 +272,7 @@
\section1 Setting up FSF GDB for Mac OS
To use FSF GDB on Mac OS, you must sign it and add it to the \QC tool
chains.
To use FSF GDB on Mac OS, you must sign it and add it to the \QC targets.
\list 1
@@ -317,21 +313,14 @@
\endcode
\o In \QC, select \gui {Qt Creator > Preferences > Build & Run >
Tool Chains}, to add a tool chain that uses the debugger:
\list 1
\o Select a native tool chain (usually, a x86 64-bit tool chain)
and click \gui Clone to clone it.
Targets} > \gui Add to create a build target that uses FSF GDB.
\o In the \gui Debugger field, specify the path to FSF GDB
(\c $HOME/gdb72/bin/fsfgdb, but with an explicit value for
\c $HOME).
\endlist
\o To use the debugger, select the tool chain in the \gui {Tool chain}
field in the \gui {Build Settings} of the project.
\o To use the debugger, add the target in the \gui {Build Settings}
of the project.
\endlist

View File

@@ -1633,7 +1633,9 @@ class Dumper:
self.putPointerValue(value.address)
return
if type.code == MethodPointerCode or type.code == MemberPointerCode:
if type.code == MethodPointerCode \
or type.code == MethodCode \
or type.code == MemberPointerCode:
self.putType(typeName)
self.putAddress(value.address)
self.putValue(value)

View File

@@ -2417,6 +2417,28 @@ def qdump__CPlusPlus__ByteArrayRef(d, value):
Hex2EncodedLatin1)
d.putPlainChildren(value)
def qdump__CPlusPlus__Identifier(d, value):
d.putValue(encodeCharArray(value["_chars"]), Hex2EncodedLatin1)
d.putPlainChildren(value)
def qdump__CPlusPlus__IntegerType(d, value):
d.putValue(value["_kind"])
d.putPlainChildren(value)
def qdump__CPlusPlus__NamedType(d, value):
literal = downcast(value["_name"])
d.putValue(encodeCharArray(literal["_chars"]), Hex2EncodedLatin1)
d.putPlainChildren(value)
def qdump__CPlusPlus__TemplateNameId(d, value):
s = encodeCharArray(value["_identifier"]["_chars"])
d.putValue(s + "3c2e2e2e3e", Hex2EncodedLatin1)
d.putPlainChildren(value)
def qdump__CPlusPlus__Literal(d, value):
d.putValue(encodeCharArray(value["_chars"]), Hex2EncodedLatin1)
d.putPlainChildren(value)
def qdump__CPlusPlus__Internal__Value(d, value):
d.putValue(value["l"])
d.putPlainChildren(value)

View File

@@ -40,17 +40,6 @@ Rectangle {
Rectangle {
id: canvas
opacity: 0
Component.onCompleted: canvas.opacity = 1
Behavior on opacity {
PropertyAnimation {
duration: 450
}
}
width: Math.min(1024, parent.width)
//this is a workaround for QTCREATORBUG-6803
anchors.topMargin: (root.height > 700) ? 0 : 0

View File

@@ -668,6 +668,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
// It gets a bit complicated if the reference is actually a class template because we
// now must worry about dependent names in base classes.
if (Template *templ = referenceClass->enclosingTemplate()) {
const unsigned argumentCount = templId->templateArgumentCount();
QHash<const Name*, unsigned> templParams;
for (unsigned i = 0; i < templ->templateParameterCount(); ++i)
templParams.insert(templ->templateParameterAt(i)->name(), i);
@@ -679,15 +680,20 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
// This is the simple case in which a template parameter is itself a base.
// Ex.: template <class T> class A : public T {};
if (templParams.contains(nameId)) {
const unsigned parameterIndex = templParams.value(nameId);
if (parameterIndex < argumentCount) {
const FullySpecifiedType &fullType =
templId->templateArgumentAt(templParams.value(nameId));
templId->templateArgumentAt(parameterIndex);
if (fullType.isValid()) {
if (NamedType *namedType = fullType.type()->asNamedType())
baseBinding = lookupType(namedType->name());
}
}
}
} else {
SubstitutionMap map;
for (unsigned i = 0;
i < templ->templateParameterCount() && i < templId->templateArgumentCount();
i < templ->templateParameterCount() && i < argumentCount;
++i) {
map.bind(templ->templateParameterAt(i)->name(),
templId->templateArgumentAt(i));

View File

@@ -276,7 +276,7 @@ extern "C" HRESULT CALLBACK pid(CIDebugClient *client, PCSTR args)
int token;
commandTokens<StringList>(args, &token);
dprintf("Qt Creator CDB extension version 0.11 (Qt 5 support) %d bit built %s.\n", sizeof(void *) > 4 ? 64 : 32, __DATE__);
dprintf("Qt Creator CDB extension version 2.6 (Qt 5 support) %d bit built %s.\n", sizeof(void *) > 4 ? 64 : 32, __DATE__);
if (const ULONG pid = currentProcessId(client)) {
ExtensionContext::instance().report('R', token, 0, "pid", "%u", pid);
} else {

View File

@@ -305,7 +305,7 @@ bool FancyLineEdit::hasAutoHideButton(Side side) const
void FancyLineEdit::setHistoryCompleter(const QString &historyKey)
{
QTC_ASSERT(!d->m_historyCompleter, return);
d->m_historyCompleter = new HistoryCompleter(this, historyKey);
d->m_historyCompleter = new HistoryCompleter(this, historyKey, this);
QLineEdit::setCompleter(d->m_historyCompleter);
}

View File

@@ -156,8 +156,9 @@ void HistoryCompleterPrivate::saveEntry(const QString &str)
theSettings->setValue(historyKey, list);
}
HistoryCompleter::HistoryCompleter(QLineEdit *lineEdit, const QString &historyKey)
: d(new HistoryCompleterPrivate)
HistoryCompleter::HistoryCompleter(QLineEdit *lineEdit, const QString &historyKey, QObject *parent)
: QCompleter(parent),
d(new HistoryCompleterPrivate)
{
QTC_ASSERT(lineEdit, return);
QTC_ASSERT(!historyKey.isEmpty(), return);
@@ -180,7 +181,9 @@ HistoryCompleter::~HistoryCompleter()
bool HistoryCompleter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress && static_cast<QKeyEvent *>(event)->key() == Qt::Key_Down) {
if (event->type() == QEvent::KeyPress &&
static_cast<QKeyEvent *>(event)->key() == Qt::Key_Down &&
static_cast<QLineEdit *>(widget())->text().isEmpty()) {
setCompletionPrefix(QString());
complete();
}

View File

@@ -49,7 +49,7 @@ class QTCREATOR_UTILS_EXPORT HistoryCompleter : public QCompleter
public:
static void setSettings(QSettings *settings);
HistoryCompleter(QLineEdit *lineEdit, const QString &historyKey);
HistoryCompleter(QLineEdit *lineEdit, const QString &historyKey, QObject *parent = 0);
private:
~HistoryCompleter();

View File

@@ -91,7 +91,7 @@
<item>
<widget class="QCheckBox" name="hijackedCheckBox">
<property name="text">
<string>Use &amp;Hijacked file</string>
<string extracomment="Hijack: Unset read-only flag without check-out. This is used for local changes which the user does not want to commit.">Use &amp;Hijacked file</string>
</property>
<property name="checked">
<bool>true</bool>

View File

@@ -217,6 +217,8 @@ QString ClearCasePlugin::findTopLevel(const QString &directory) const
if (!topLevel.isEmpty() || !clearCaseControl()->isConfigured())
return topLevel;
// Dynamic view
if (directory.startsWith(m_topLevel) && directory.at(m_topLevel.size()) == QLatin1Char('/'))
return m_topLevel;
bool isDynamic;
ccGetView(directory, &isDynamic);
if (isDynamic) {
@@ -708,7 +710,7 @@ void ClearCasePlugin::undoHijackCurrent()
Ui::UndoCheckOut unhijackUi;
QDialog unhijackDlg;
unhijackUi.setupUi(&unhijackDlg);
unhijackDlg.setWindowTitle(tr("Undo hijack file"));
unhijackDlg.setWindowTitle(tr("Undo Hijack File"));
unhijackUi.lblMessage->setText(tr("Do you want to undo hijack of '%1'?")
.arg(QDir::toNativeSeparators(fileName)));
if (unhijackDlg.exec() != QDialog::Accepted)
@@ -1183,7 +1185,7 @@ ClearCaseResponse
ClearCaseResponse response;
if (executable.isEmpty()) {
response.error = true;
response.message = tr("No ClearCase executable specified!");
response.message = tr("No ClearCase executable specified.");
return response;
}
@@ -1267,7 +1269,7 @@ bool ClearCasePlugin::vcsOpen(const QString &workingDir, const QString &fileName
(fi.isWritable() || s_statusMap[relFile].status == FileStatus::Unknown))
QtConcurrent::run(&sync, topLevel, QStringList(relFile)).waitForFinished();
if (s_statusMap[relFile].status == FileStatus::CheckedOut) {
QMessageBox::information(0, tr("ClearCase Checkout"), tr("File is already checked out!"));
QMessageBox::information(0, tr("ClearCase Checkout"), tr("File is already checked out."));
return true;
}
bool isHijacked = (s_statusMap[relFile].status & FileStatus::Hijacked);
@@ -1490,7 +1492,7 @@ bool ClearCasePlugin::vcsAdd(const QString &workingDir, const QString &fileName)
bool ClearCasePlugin::vcsDelete(const QString &workingDir, const QString &fileName)
{
const QString title(tr("ClearCase Remove Element"));
if (QMessageBox::warning(0, title, tr("This operation is irreversible! Are you sure?"),
if (QMessageBox::warning(0, title, tr("This operation is irreversible. Are you sure?"),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return true;
@@ -1542,31 +1544,31 @@ QList<QStringPair> ClearCasePlugin::ccGetActivities() const
// Maintain latest deliver and rebase activities only
QStringPair rebaseAct;
QStringPair deliverAct;
QStringList args(QLatin1String("lsactivity"));
// Retrieve all activities
QStringList args(QLatin1String("lsactivity"));
args << QLatin1String("-fmt") << QLatin1String("%n\\t%[headline]p\\n");
const QString response = runCleartoolSync(currentState().topLevel(), args);
QStringList acts = response.split(QLatin1Char('\n'), QString::SkipEmptyParts);
foreach (QString activity, acts) {
QStringList act = activity.split(QLatin1Char('\t'));
// exclude deliver/rebase activities (and include only the latest ones)
QRegExp deliverRebase(QLatin1String("deliver\\.|rebase\\."));
if (act.size() >= 2)
{
QString actName = act.at(0);
if (actName.indexOf(deliverRebase) == -1)
result.append(QStringPair(actName, act.at(1).trimmed()));
else if ((actName.at(0) == QLatin1Char('r')) && (actName > rebaseAct.first))
// include only latest deliver/rebase activities. Activities are sorted
// by creation time
if (actName.startsWith(QLatin1String("rebase.")))
rebaseAct = QStringPair(actName, act.at(1));
else if ((actName.at(0) == QLatin1Char('d')) && (actName > deliverAct.first))
else if (actName.startsWith(QLatin1String("deliver.")))
deliverAct = QStringPair(actName, act.at(1));
else
result.append(QStringPair(actName, act.at(1).trimmed()));
}
}
qSort(result);
if (!rebaseAct.first.isEmpty())
result.append(rebaseAct);
if (!deliverAct.first.isEmpty())
result.append(deliverAct);
qSort(result);
return result;
}

View File

@@ -161,7 +161,7 @@
<item row="9" column="0">
<widget class="QLabel" name="indexOnlyVOBsLabel">
<property name="text">
<string>&amp;Index only VOBs:</string>
<string extracomment="VOB: Versioned Object Base">&amp;Index only VOBs:</string>
</property>
<property name="buddy">
<cstring>indexOnlyVOBsEdit</cstring>

View File

@@ -63,7 +63,7 @@
</palette>
</property>
<property name="text">
<string>The file was changed!</string>
<string>The file was changed.</string>
</property>
</widget>
</item>

View File

@@ -45,6 +45,9 @@ VersionSelector::VersionSelector(const QString &fileName, const QString &message
{
ui->setupUi(this);
ui->headerLabel->setText(ui->headerLabel->text().arg(fileName));
ui->loadedText->setHtml(tr("<html><head/><body><p><b>NOTE: You will not be able to check in "
"this file without merging the changes (not supported by the "
"plugin)</b></p></body></html>"));
m_stream = new QTextStream(message.toLocal8Bit(), QIODevice::ReadOnly | QIODevice::Text);
QString line;
while (!m_stream->atEnd() && !line.contains(QLatin1String("1) Loaded version")))

View File

@@ -75,15 +75,7 @@
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QTextEdit" name="loadedText">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; font-weight:600;&quot;&gt;NOTE: You will not be able to check in this file without merging the changes (not supported by the plugin)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QTextEdit" name="loadedText"/>
</item>
</layout>
</item>
@@ -113,7 +105,7 @@ p, li { white-space: pre-wrap; }
<item row="2" column="0">
<widget class="QLabel" name="updatedCreatedOnHeaderLabel">
<property name="text">
<string>Created On:</string>
<string extracomment="Date">Created On:</string>
</property>
</widget>
</item>

View File

@@ -107,7 +107,7 @@ static int theId(const char *str)
if (lastUid == 0)
stringFromId.append(QByteArray());
res = ++lastUid;
sh.str = strdup(sh.str);
sh.str = qstrdup(sh.str);
idFromString[sh] = res;
stringFromId.append(QByteArray::fromRawData(sh.str, sh.n));
}

View File

@@ -163,7 +163,7 @@ public:
m_targetState(DebuggerNotReady),
m_remoteSetupState(RemoteSetupNone),
m_inferiorPid(0),
m_modulesHandler(),
m_modulesHandler(engine),
m_registerHandler(),
m_sourceFilesHandler(),
m_stackHandler(),

View File

@@ -54,10 +54,10 @@
namespace Debugger {
namespace Internal {
class GdbOptionsPagePrivate : public QWidget
class GdbOptionsPageWidget : public QWidget
{
public:
explicit GdbOptionsPagePrivate(QWidget *parent);
explicit GdbOptionsPageWidget(QWidget *parent);
QGroupBox *groupBoxGeneral;
QLabel *labelGdbWatchdogTimeout;
@@ -91,7 +91,7 @@ public:
QString searchKeywords;
};
GdbOptionsPagePrivate::GdbOptionsPagePrivate(QWidget *parent)
GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent)
: QWidget(parent)
{
groupBoxGeneral = new QGroupBox(this);
@@ -190,7 +190,7 @@ GdbOptionsPagePrivate::GdbOptionsPagePrivate(QWidget *parent)
checkBoxBreakOnFatal->setText(GdbOptionsPage::tr("Stop when qFatal() is called"));
checkBoxBreakOnFatal->setToolTip(GdbOptionsPage::tr(
"<html><head/><body>Always add a breakpoint on the <i>qFatal()</i> function."
"/body></html>"));
"</body></html>"));
checkBoxBreakOnAbort = new QCheckBox(groupBoxGeneral);
checkBoxBreakOnAbort->setText(GdbOptionsPage::tr("Stop when abort() is called"));
@@ -338,7 +338,6 @@ GdbOptionsPagePrivate::GdbOptionsPagePrivate(QWidget *parent)
}
GdbOptionsPage::GdbOptionsPage()
: d(0)
{
setId(QLatin1String("M.Gdb"));
setDisplayName(tr("GDB"));
@@ -349,30 +348,29 @@ GdbOptionsPage::GdbOptionsPage()
GdbOptionsPage::~GdbOptionsPage()
{
delete d;
}
QWidget *GdbOptionsPage::createPage(QWidget *parent)
{
d = new GdbOptionsPagePrivate(parent);
return d;
m_widget = new GdbOptionsPageWidget(parent);
return m_widget;
}
void GdbOptionsPage::apply()
{
if (d)
d->group.apply(Core::ICore::settings());
if (m_widget)
m_widget->group.apply(Core::ICore::settings());
}
void GdbOptionsPage::finish()
{
if (d)
d->group.finish();
if (m_widget)
m_widget->group.finish();
}
bool GdbOptionsPage::matches(const QString &s) const
{
return d && d->searchKeywords.contains(s, Qt::CaseInsensitive);
return m_widget && m_widget->searchKeywords.contains(s, Qt::CaseInsensitive);
}
} // namespace Internal

View File

@@ -32,11 +32,12 @@
#define GDBOPTIONSPAGE_H
#include <coreplugin/dialogs/ioptionspage.h>
#include <QPointer>
namespace Debugger {
namespace Internal {
class GdbOptionsPagePrivate;
class GdbOptionsPageWidget;
class GdbOptionsPage : public Core::IOptionsPage
{
@@ -51,7 +52,7 @@ public:
bool matches(const QString &) const;
private:
GdbOptionsPagePrivate *d;
QPointer<GdbOptionsPageWidget> m_widget;
};
} // namespace Internal

View File

@@ -228,6 +228,7 @@ void ModulesModel::removeModule(const QString &modulePath)
void ModulesModel::updateModule(const Module &module)
{
const int row = indexOfModule(module.modulePath);
try { // MinGW occasionallly throws std::bad_alloc.
ElfReader reader(module.modulePath);
ElfData elfData = reader.readHeaders();
@@ -242,6 +243,10 @@ void ModulesModel::updateModule(const Module &module)
m_modules[row].elfData = elfData;
dataChanged(index(row, 0, QModelIndex()), index(row, 4, QModelIndex()));
}
} catch(...) {
qWarning("%s: An exception occurred while reading module '%s'",
Q_FUNC_INFO, qPrintable(module.modulePath));
}
}
//////////////////////////////////////////////////////////////////
@@ -250,8 +255,9 @@ void ModulesModel::updateModule(const Module &module)
//
//////////////////////////////////////////////////////////////////
ModulesHandler::ModulesHandler()
ModulesHandler::ModulesHandler(DebuggerEngine *engine)
{
m_engine = engine;
m_model = new ModulesModel(this);
m_proxyModel = new QSortFilterProxyModel(this);
m_proxyModel->setSourceModel(m_model);

View File

@@ -42,6 +42,9 @@ class QSortFilterProxyModel;
QT_END_NAMESPACE
namespace Debugger {
class DebuggerEngine;
namespace Internal {
class ModulesModel;
@@ -105,7 +108,7 @@ class ModulesHandler : public QObject
Q_OBJECT
public:
ModulesHandler();
explicit ModulesHandler(DebuggerEngine *engine);
QAbstractItemModel *model() const;
@@ -117,6 +120,7 @@ public:
void removeAll();
private:
DebuggerEngine *m_engine;
ModulesModel *m_model;
QSortFilterProxyModel *m_proxyModel;
};

View File

@@ -116,7 +116,7 @@ QString StackFrame::toToolTip() const
} else {
str << tr("Binary debug information is accessible for this "
"frame. However, matching sources have not been found. "
"Note that some distributions ship debug sources in "
"Note that some distributions ship debug sources "
"in separate packages.");
}

View File

@@ -121,16 +121,16 @@ void Qt4MaemoDeployConfiguration::setupDebianPackaging()
return;
Utils::FileName debianDir = DebianManager::debianDirectory(target());
Core::Id deviceType = ProjectExplorer::DeviceTypeProfileInformation::deviceTypeId(target()->profile());
DebianManager *dm = DebianManager::instance();
QString projectName = target()->project()->displayName();
DebianManager::ActionStatus status = DebianManager::createTemplate(bc, debianDir);
if (status == DebianManager::NoActionRequired ||
status == DebianManager::ActionFailed)
return;
Core::Id deviceType = ProjectExplorer::DeviceTypeProfileInformation::deviceTypeId(target()->profile());
DebianManager *dm = DebianManager::instance();
QString projectName = target()->project()->displayName();
if (!DebianManager::hasPackageManagerIcon(debianDir)) {
// Such a file is created by the mobile wizards.
Utils::FileName iconPath = Utils::FileName::fromString(target()->project()->projectDirectory());
@@ -249,7 +249,9 @@ DeployConfiguration *Qt4MaemoDeployConfigurationFactory::create(Target *parent,
Q_ASSERT(canCreate(parent, id));
const QString displayName = displayNameForId(id);
DeployConfiguration * const dc = new Qt4MaemoDeployConfiguration(parent, id, displayName);
Qt4MaemoDeployConfiguration * const dc = new Qt4MaemoDeployConfiguration(parent, id, displayName);
dc->setupDebianPackaging();
if (id == Qt4MaemoDeployConfiguration::fremantleWithoutPackagingId()) {
dc->stepList()->insertStep(0, new MaemoMakeInstallToSysrootStep(dc->stepList()));
dc->stepList()->insertStep(1, new RemoteLinuxCheckForFreeDiskSpaceStep(dc->stepList()));

View File

@@ -643,7 +643,7 @@ Abi Abi::hostAbi()
subos = WindowsMsvc2008Flavor;
#elif _MSC_VER == 1400
subos = WindowsMsvc2005Flavor;
#elif defined (mingw32)
#elif defined (Q_CC_MINGW)
subos = WindowsMSysFlavor;
#endif
format = PEFormat;

View File

@@ -49,7 +49,6 @@
#include <utils/persistentsettings.h>
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QMessageBox>
@@ -659,7 +658,7 @@ QVariantMap SettingsAccessor::restoreSettings() const
// Time to consider shared settings...
SettingsData sharedSettings;
if (m_sharedFileAcessor.readFile(&sharedSettings)) {
if (!sharedSettings.m_fileName.isEmpty() && m_sharedFileAcessor.readFile(&sharedSettings)) {
bool useSharedSettings = true;
if (sharedSettings.m_version != settings.m_version) {
int baseFileVersion;
@@ -2326,23 +2325,34 @@ QVariantMap Version11Handler::update(Project *project, const QVariantMap &map)
if (oldTargetId == QLatin1String("Qt4ProjectManager.Target.AndroidDeviceTarget")) {
tmpProfile->setIconPath(QLatin1String(":/android/images/QtAndroid.png"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("Desktop"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString());
} else if (oldTargetId == QLatin1String("RemoteLinux.EmbeddedLinuxTarget")) {
tmpProfile->setIconPath(QLatin1String(":///DESKTOP///"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("GenericLinuxOsType"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString());
} else if (oldTargetId == QLatin1String("Qt4ProjectManager.Target.HarmattanDeviceTarget")) {
tmpProfile->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("HarmattanOsType"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString());
} else if (oldTargetId == QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget")) {
tmpProfile->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("Maemo5OsType"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString());
} else if (oldTargetId == QLatin1String("Qt4ProjectManager.Target.MeegoDeviceTarget")) {
tmpProfile->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("MeegoOsType"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString());
} else if (oldTargetId == QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget")) {
tmpProfile->setIconPath(QLatin1String(":/projectexplorer/images/SymbianDevice.png"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("Qt4ProjectManager.SymbianDevice"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString::fromLatin1("Symbian Device"));
} else if (oldTargetId == QLatin1String("Qt4ProjectManager.Target.QtSimulatorTarget")) {
tmpProfile->setIconPath(QLatin1String(":/projectexplorer/images/Simulator.png"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("Desktop"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString::fromLatin1("Desktop Device"));
} else {
tmpProfile->setIconPath(QLatin1String(":///DESKTOP///"));
tmpProfile->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("Desktop"));
tmpProfile->setValue(Core::Id("PE.Profile.Device"), QString::fromLatin1("Desktop Device"));
}
@@ -2428,24 +2438,34 @@ QVariantMap Version11Handler::update(Project *project, const QVariantMap &map)
Profile *Version11Handler::uniqueProfile(Profile *p)
{
foreach (Profile *i, m_targets.keys()) {
const QString tc = i->value(Core::Id("PE.Profile.ToolChain")).toString();
const int qt = i->value(Core::Id("QtSupport.QtInformation")).toInt();
const QString debugger = i->value(Core::Id("Debugger.Information")).toString();
const QString mkspec = i->value(Core::Id("QtPM4.mkSpecInformation")).toString();
const QString device = i->value(Core::Id("PE.Profile.Device")).toString();
const QString tc = p->value(Core::Id("PE.Profile.ToolChain")).toString();
const int qt = p->value(Core::Id("QtSupport.QtInformation")).toInt();
const QString debugger = p->value(Core::Id("Debugger.Information")).toString();
const QString mkspec = p->value(Core::Id("QtPM4.mkSpecInformation")).toString();
const QString deviceType = p->value(Core::Id("PE.Profile.DeviceType")).toString();
const QString device = p->value(Core::Id("PE.Profile.Device")).toString();
const QString sysroot = p->value(Core::Id("PE.Profile.SysRoot")).toString();
if ((i->value(Core::Id("PE.Profile.DeviceType")).toString() == p->value(Core::Id("PE.Profile.DeviceType")).toString())
&& (tc.isEmpty() || (tc == p->value(Core::Id("PE.Profile.ToolChain")).toString()))
&& (qt == p->value(Core::Id("QtSupport.QtInformation")).toInt())
&& (debugger.isEmpty() || (debugger == p->value(Core::Id("Debugger.Information")).toString()))
&& (mkspec.isEmpty() || (mkspec == p->value(Core::Id("QtPM4.mkSpecInformation")).toString()))
&& (i->value(Core::Id("PE.Profile.SysRoot")).toString() == p->value(Core::Id("PE.Profile.SysRoot")).toString())
&& (device == p->value(Core::Id("PE.Profile.Device")))) {
foreach (Profile *i, m_targets.keys()) {
const QString currentTc = i->value(Core::Id("PE.Profile.ToolChain")).toString();
const int currentQt = i->value(Core::Id("QtSupport.QtInformation")).toInt();
const QString currentDebugger = i->value(Core::Id("Debugger.Information")).toString();
const QString currentMkspec = i->value(Core::Id("QtPM4.mkSpecInformation")).toString();
const QString currentDeviceType = i->value(Core::Id("PE.Profile.DeviceType")).toString();
const QString currentDevice = i->value(Core::Id("PE.Profile.Device")).toString();
const QString currentSysroot = i->value(Core::Id("PE.Profile.SysRoot")).toString();
bool deviceTypeOk = deviceType == currentDeviceType;
bool deviceOk = device.isEmpty() || currentDevice == device;
bool tcOk = tc.isEmpty() || currentTc.isEmpty() || currentTc == tc;
bool qtOk = qt == -1 || currentQt == qt;
bool debuggerOk = debugger.isEmpty() || currentDebugger.isEmpty() || currentDebugger == debugger;
bool mkspecOk = mkspec.isEmpty() || currentMkspec.isEmpty() || currentMkspec == mkspec;
bool sysrootOk = sysroot.isEmpty() || currentSysroot == sysroot;
if (deviceTypeOk && deviceOk && tcOk && qtOk && debuggerOk && mkspecOk && sysrootOk)
return i;
}
}
return p->clone(true);
}

View File

@@ -48,7 +48,7 @@ BlackBerryDeployInformation::BlackBerryDeployInformation(Qt4ProjectManager::Qt4P
: QAbstractTableModel(project)
, m_project(project)
{
connect(m_project, SIGNAL(buildSystemEvaluated()), this, SLOT(initModel()));
connect(m_project, SIGNAL(proFilesEvaluated()), this, SLOT(initModel()));
}
int BlackBerryDeployInformation::rowCount(const QModelIndex &parent) const
@@ -175,7 +175,7 @@ void BlackBerryDeployInformation::initModel()
if (!rootNode || rootNode->parseInProgress()) // Can be null right after project creation by wizard.
return;
disconnect(m_project, SIGNAL(buildSystemEvaluated()), this, SLOT(initModel()));
disconnect(m_project, SIGNAL(proFilesEvaluated()), this, SLOT(initModel()));
beginResetModel();
m_deployInformation.clear();
@@ -193,5 +193,5 @@ void BlackBerryDeployInformation::initModel()
}
endResetModel();
connect(m_project, SIGNAL(buildSystemEvaluated()), SLOT(initModel()));
connect(m_project, SIGNAL(proFilesEvaluated()), SLOT(initModel()));
}

View File

@@ -1097,8 +1097,10 @@ QStringList Qt4Project::applicationProFilePathes(const QString &prepend) const
void Qt4Project::activeTargetWasChanged()
{
if (m_activeTarget) {
disconnect(m_activeTarget, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
this, SLOT(scheduleAsyncUpdate()));
}
m_activeTarget = activeTarget();

View File

@@ -136,7 +136,7 @@ QtVersionManager::QtVersionManager() :
void QtVersionManager::extensionsInitialized()
{
bool success = restoreQtVersions();
updateFromInstaller();
updateFromInstaller(false);
if (!success) {
// We did neither restore our settings or upgraded
// in that case figure out if there's a qt in path
@@ -144,6 +144,7 @@ void QtVersionManager::extensionsInitialized()
findSystemQt();
}
emit qtVersionsChanged(m_versions.keys(), QList<int>(), QList<int>());
saveQtVersions();
const Utils::FileName configFileName = globalSettingsFileName();
@@ -231,7 +232,7 @@ bool QtVersionManager::restoreQtVersions()
return true;
}
void QtVersionManager::updateFromInstaller()
void QtVersionManager::updateFromInstaller(bool emitSignal)
{
m_fileWatcherTimer->stop();
@@ -353,6 +354,7 @@ void QtVersionManager::updateFromInstaller()
qDebug() << "";
}
}
if (emitSignal)
emit qtVersionsChanged(added, removed, changed);
saveQtVersions();
}

View File

@@ -109,7 +109,7 @@ public slots:
void updateDumpFor(const Utils::FileName &qmakeCommand);
private slots:
void updateFromInstaller();
void updateFromInstaller(bool emitSignal = true);
private:
// This function is really simplistic...

View File

@@ -33,6 +33,7 @@
#include <QFileInfo>
#include <QSet>
#include <QStringList>
#include <QTextStream>
QT_BEGIN_NAMESPACE
@@ -155,39 +156,6 @@ QString &ProString::toQString(QString &tmp) const
return tmp.setRawData(m_string.constData() + m_offset, m_length);
}
bool ProString::operator==(const ProString &other) const
{
if (m_length != other.m_length)
return false;
return !memcmp(m_string.constData() + m_offset,
other.m_string.constData() + other.m_offset, m_length * 2);
}
bool ProString::operator==(const QString &other) const
{
if (m_length != other.length())
return false;
return !memcmp(m_string.constData() + m_offset, other.constData(), m_length * 2);
}
bool ProString::operator==(const QLatin1String &other) const
{
const ushort *uc = (ushort *)m_string.constData() + m_offset;
const ushort *e = uc + m_length;
const uchar *c = (uchar *)other.latin1();
if (!c)
return isEmpty();
while (*c) {
if (uc == e || *uc != *c)
return false;
++uc;
++c;
}
return (uc == e);
}
QChar *ProString::prepareAppend(int extraLen)
{
if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) {
@@ -299,7 +267,7 @@ ProString ProString::mid(int off, int len) const
off = m_length;
ret.m_offset += off;
ret.m_length -= off;
if (ret.m_length > len)
if ((uint)ret.m_length > (uint)len) // Unsigned comparison to interpret < 0 as infinite
ret.m_length = len;
return ret;
}
@@ -322,6 +290,12 @@ ProString ProString::trimmed() const
return ret;
}
QTextStream &operator<<(QTextStream &t, const ProString &str)
{
t << str.toQString(); // XXX optimize ... somehow
return t;
}
QString ProStringList::join(const QString &sep) const
{
int totalLength = 0;
@@ -346,6 +320,20 @@ QString ProStringList::join(const QString &sep) const
return res;
}
void ProStringList::removeAll(const ProString &str)
{
for (int i = size(); --i >= 0; )
if (at(i) == str)
remove(i);
}
void ProStringList::removeAll(const char *str)
{
for (int i = size(); --i >= 0; )
if (at(i) == str)
remove(i);
}
void ProStringList::removeDuplicates()
{
int n = size();
@@ -365,6 +353,13 @@ void ProStringList::removeDuplicates()
erase(begin() + j, end());
}
ProStringList::ProStringList(const QStringList &list)
{
reserve(list.size());
foreach (const QString &str, list)
*this << ProString(str);
}
QStringList ProStringList::toQStringList() const
{
QStringList ret;
@@ -374,6 +369,22 @@ QStringList ProStringList::toQStringList() const
return ret;
}
bool ProStringList::contains(const ProString &str, Qt::CaseSensitivity cs) const
{
for (int i = 0; i < size(); i++)
if (!at(i).compare(str, cs))
return true;
return false;
}
bool ProStringList::contains(const char *str, Qt::CaseSensitivity cs) const
{
for (int i = 0; i < size(); i++)
if (!at(i).compare(str, cs))
return true;
return false;
}
ProFile::ProFile(const QString &fileName)
: m_refCount(1),
m_fileName(fileName),

View File

@@ -32,12 +32,15 @@
#define PROITEMS_H
#include "qmake_global.h"
#include <QString>
#include <QVector>
#include <QHash>
QT_BEGIN_NAMESPACE
class QTextStream;
#ifdef PROPARSER_THREAD_SAFE
typedef QAtomicInt ProItemRefCount;
#else
@@ -52,6 +55,12 @@ private:
};
#endif
#ifndef QT_BUILD_QMAKE
# define PROITEM_EXPLICIT explicit
#else
# define PROITEM_EXPLICIT
#endif
class ProKey;
class ProStringList;
class ProFile;
@@ -60,39 +69,75 @@ class ProString {
public:
ProString();
ProString(const ProString &other);
explicit ProString(const QString &str);
explicit ProString(const char *str);
PROITEM_EXPLICIT ProString(const QString &str);
PROITEM_EXPLICIT ProString(const char *str);
ProString(const QString &str, int offset, int length);
void setValue(const QString &str);
void clear() { m_string.clear(); m_length = 0; }
ProString &setSource(const ProString &other) { m_file = other.m_file; return *this; }
ProString &setSource(const ProFile *pro) { m_file = pro; return *this; }
const ProFile *sourceFile() const { return m_file; }
QString toQString() const;
QString &toQString(QString &tmp) const;
ProString &operator+=(const ProString &other);
ProString &append(const ProString &other, bool *pending = 0);
ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false);
bool operator==(const ProString &other) const;
bool operator==(const QString &other) const;
bool operator==(const QLatin1String &other) const;
void chop(int n) { Q_ASSERT(n <= m_length); m_length -= n; }
void chopFront(int n) { Q_ASSERT(n <= m_length); m_offset += n; m_length -= n; }
bool operator==(const ProString &other) const { return toQStringRef() == other.toQStringRef(); }
bool operator==(const QString &other) const { return toQStringRef() == other; }
bool operator==(QLatin1String other) const { return toQStringRef() == other; }
bool operator==(const char *other) const { return toQStringRef() == QLatin1String(other); }
bool operator!=(const ProString &other) const { return !(*this == other); }
bool operator!=(const QString &other) const { return !(*this == other); }
bool operator!=(const QLatin1String &other) const { return !(*this == other); }
bool operator!=(QLatin1String other) const { return !(*this == other); }
bool operator!=(const char *other) const { return !(*this == other); }
bool isNull() const { return m_string.isNull(); }
bool isEmpty() const { return !m_length; }
int length() const { return m_length; }
int size() const { return m_length; }
QChar at(int i) const { Q_ASSERT((uint)i < (uint)m_length); return constData()[i]; }
const QChar *constData() const { return m_string.constData() + m_offset; }
ProString mid(int off, int len = -1) const;
ProString left(int len) const { return mid(0, len); }
ProString right(int len) const { return mid(qMax(0, size() - len)); }
ProString trimmed() const;
void clear() { m_string.clear(); m_length = 0; }
int compare(const ProString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(sub.toQStringRef(), cs); }
int compare(const QString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(sub, cs); }
int compare(const char *sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(QLatin1String(sub), cs); }
bool startsWith(const ProString &sub) const { return toQStringRef().startsWith(sub.toQStringRef()); }
bool startsWith(const QString &sub) const { return toQStringRef().startsWith(sub); }
bool startsWith(const char *sub) const { return toQStringRef().startsWith(QLatin1String(sub)); }
bool startsWith(QChar c) const { return toQStringRef().startsWith(c); }
bool endsWith(const ProString &sub) const { return toQStringRef().endsWith(sub.toQStringRef()); }
bool endsWith(const QString &sub) const { return toQStringRef().endsWith(sub); }
bool endsWith(const char *sub) const { return toQStringRef().endsWith(QLatin1String(sub)); }
bool endsWith(QChar c) const { return toQStringRef().endsWith(c); }
int indexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().indexOf(s, from, cs); }
int indexOf(const char *s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().indexOf(QLatin1String(s), from, cs); }
int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().indexOf(c, from, cs); }
int lastIndexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().lastIndexOf(s, from, cs); }
int lastIndexOf(const char *s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().lastIndexOf(QLatin1String(s), from, cs); }
int lastIndexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().lastIndexOf(c, from, cs); }
bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; }
bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; }
bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; }
int toInt(bool *ok = 0) const { return toQString().toInt(ok); } // XXX optimize
short toShort(bool *ok = 0) const { return toQString().toShort(ok); } // XXX optimize
static uint hash(const QChar *p, int n);
ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, m_offset, m_length); }
ALWAYS_INLINE ProKey &toKey() { return *(ProKey *)this; }
ALWAYS_INLINE const ProKey &toKey() const { return *(const ProKey *)this; }
QString toQString() const;
QString &toQString(QString &tmp) const;
QByteArray toLatin1() const { return toQStringRef().toLatin1(); }
private:
ProString(const ProKey &other);
ProString &operator=(const ProKey &other);
@@ -122,7 +167,7 @@ class ProKey : public ProString {
public:
ALWAYS_INLINE ProKey() : ProString() {}
explicit ProKey(const QString &str);
explicit ProKey(const char *str);
PROITEM_EXPLICIT ProKey(const char *str);
ProKey(const QString &str, int off, int len);
ProKey(const QString &str, int off, int len, uint hash);
void setValue(const QString &str);
@@ -152,15 +197,49 @@ inline QString operator+(const ProString &one, const QString &two)
inline QString operator+(const QString &one, const ProString &two)
{ return ProString(one) + two; }
inline QString operator+(const ProString &one, const char *two)
{ return one + ProString(two); } // XXX optimize
inline QString operator+(const char *one, const ProString &two)
{ return ProString(one) + two; } // XXX optimize
inline QString &operator+=(QString &that, const ProString &other)
{ return that += other.toQStringRef(); }
inline bool operator==(const QString &that, const ProString &other)
{ return other == that; }
inline bool operator!=(const QString &that, const ProString &other)
{ return !(other == that); }
QTextStream &operator<<(QTextStream &t, const ProString &str);
class ProStringList : public QVector<ProString> {
public:
ProStringList() {}
ProStringList(const ProString &str) { *this << str; }
QString join(const QString &sep) const;
void removeDuplicates();
explicit ProStringList(const QStringList &list);
QStringList toQStringList() const;
ProStringList &operator<<(const ProString &str)
{ QVector<ProString>::operator<<(str); return *this; }
int length() const { return size(); }
QString join(const QString &sep) const;
void removeAll(const ProString &str);
void removeAll(const char *str);
void removeAt(int idx) { remove(idx); }
void removeDuplicates();
bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return contains(ProString(str), cs); }
bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
};
inline ProStringList operator+(const ProStringList &one, const ProStringList &two)
{ ProStringList ret = one; ret += two; return ret; }
typedef QHash<ProKey, ProStringList> ProValueMap;
// These token definitions affect both ProFileEvaluator and ProWriter

View File

@@ -352,7 +352,7 @@ QByteArray QMakeEvaluator::getCommandOutput(const QString &args) const
QByteArray out;
if (FILE *proc = QT_POPEN(QString(QLatin1String("cd ")
+ IoUtils::shellQuote(currentDirectory())
+ QLatin1String(" && ") + args[0]).toLocal8Bit().constData(), "r")) {
+ QLatin1String(" && ") + args).toLocal8Bit().constData(), "r")) {
while (!feof(proc)) {
char buff[10 * 1024];
int read_in = int(fread(buff, 1, sizeof(buff), proc));
@@ -1009,7 +1009,7 @@ ProStringList QMakeEvaluator::evaluateExpandFunction(
evalError(fL1S("shell_path(path) requires one argument."));
} else {
QString rstr = args.at(0).toQString(m_tmp1);
if (m_option->dir_sep.at(0) != QLatin1Char('/'))
if (m_dirSep.startsWith(QLatin1Char('\\')))
rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
else
rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
@@ -1029,7 +1029,7 @@ ProStringList QMakeEvaluator::evaluateExpandFunction(
evalError(fL1S("shell_quote(arg) requires one argument."));
} else {
QString rstr = args.at(0).toQString(m_tmp1);
if (m_option->dir_sep.at(0) != QLatin1Char('/'))
if (m_dirSep.startsWith(QLatin1Char('\\')))
rstr = IoUtils::shellQuoteWin(rstr);
else
rstr = IoUtils::shellQuoteUnix(rstr);
@@ -1091,7 +1091,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
// they cannot be used to terminate loops anyway.
if (m_cumulative)
return ReturnTrue;
if (m_valuemapStack.isEmpty()) {
if (m_valuemapStack.size() == 1) {
evalError(fL1S("unexpected return()."));
return ReturnFalse;
}

View File

@@ -170,6 +170,7 @@ QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option,
initStatics();
// Configuration, more or less
m_caller = 0;
#ifdef PROEVALUATOR_CUMULATIVE
m_cumulative = false;
#endif
@@ -200,6 +201,7 @@ void QMakeEvaluator::initFrom(const QMakeEvaluator &other)
m_qmakespecName = other.m_qmakespecName;
m_mkspecPaths = other.m_mkspecPaths;
m_featureRoots = other.m_featureRoots;
m_dirSep = other.m_dirSep;
}
//////// Evaluator tools /////////
@@ -328,7 +330,7 @@ static void replaceInList(ProStringList *varlist,
QString val = varit->toQString(tmp);
QString copy = val; // Force detach and have a reference value
val.replace(regexp, replace);
if (!val.isSharedWith(copy)) {
if (!val.isSharedWith(copy) && val != copy) {
if (val.isEmpty()) {
varit = varlist->erase(varit);
} else {
@@ -1104,6 +1106,8 @@ bool QMakeEvaluator::loadSpec()
if (!evaluateFeatureFile(QLatin1String("spec_post.prf")))
return false;
updateFeaturePaths(); // The spec extends the feature search path, so rebuild the cache.
// The MinGW and x-build specs may change the separator; $$shell_{path,quote}() need it
m_dirSep = first(ProKey("QMAKE_DIR_SEP"));
if (!m_conffile.isEmpty()
&& !evaluateFileDirect(m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly)) {
return false;
@@ -1626,11 +1630,14 @@ bool QMakeEvaluator::evaluateFile(
{
if (fileName.isEmpty())
return false;
foreach (const ProFile *pf, m_profileStack)
QMakeEvaluator *ref = this;
do {
foreach (const ProFile *pf, ref->m_profileStack)
if (pf->fileName() == fileName) {
evalError(fL1S("Circular inclusion of %1.").arg(fileName));
return false;
}
} while ((ref = ref->m_caller));
return evaluateFileDirect(fileName, type, flags);
}
@@ -1695,7 +1702,9 @@ bool QMakeEvaluator::evaluateFileInto(const QString &fileName, QMakeHandler::Eva
ProValueMap *values, LoadFlags flags)
{
QMakeEvaluator visitor(m_option, m_parser, m_handler);
visitor.m_caller = this;
visitor.m_outputDir = m_outputDir;
visitor.m_featureRoots = m_featureRoots;
if (!visitor.evaluateFile(fileName, type, flags))
return false;
*values = visitor.m_valuemapStack.top();

View File

@@ -195,6 +195,7 @@ public:
static void removeEach(ProStringList *varlist, const ProStringList &value);
QMakeEvaluator *m_caller;
int m_loopLevel; // To report unexpected break() and next()s
#ifdef PROEVALUATOR_CUMULATIVE
bool m_cumulative;
@@ -232,6 +233,7 @@ public:
QStringList m_qmakefeatures;
QStringList m_mkspecPaths;
QStringList m_featureRoots;
ProString m_dirSep;
ProFunctionDefs m_functionDefs;
ProStringList m_returnValue;
QStack<ProValueMap> m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii.

View File

@@ -182,10 +182,11 @@ QStringList QMakeGlobals::getPathListEnv(const QString &var) const
QStringList ret;
QString val = getEnv(var);
if (!val.isEmpty()) {
QDir bdir;
QStringList vals = val.split(dirlist_sep);
ret.reserve(vals.length());
foreach (const QString &it, vals)
ret << QDir::cleanPath(it);
ret << QDir::cleanPath(bdir.absoluteFilePath(it));
}
return ret;
}

View File

@@ -82,8 +82,13 @@ static int evaluate(const QString &fileName, const QString &in_pwd, const QStrin
visitor.setOutputDir(out_pwd);
ProFile *pro;
if (!(pro = parser->parsedProFile(fileName)))
if (!(pro = parser->parsedProFile(fileName))) {
if (!QFile::exists(fileName)) {
qCritical("Input file %s does not exist.", qPrintable(fileName));
return 3;
}
return 2;
}
if (!visitor.accept(pro)) {
pro->deref();
return 2;