Merge remote-tracking branch 'origin/2.6'

Conflicts:
	src/plugins/cpptools/cppcompletion_test.cpp
	src/plugins/projectexplorer/kitmanagerconfigwidget.cpp
	src/plugins/qmlprojectmanager/qmlprojectapplicationwizard.cpp
	src/plugins/qtsupport/baseqtversion.cpp
	tests/auto/cplusplus/findusages/tst_findusages.cpp

Change-Id: Idd2abc09753a71a6c252bfa9914274459b2c7e63
This commit is contained in:
Eike Ziller
2012-11-26 10:52:28 +01:00
64 changed files with 860 additions and 324 deletions

12
.gitignore vendored
View File

@@ -111,8 +111,10 @@ bin/qml2puppet.exe
bin/qtpromaker bin/qtpromaker
bin/qtpromaker.exe bin/qtpromaker.exe
share/doc/qtcreator/*.qch share/doc/qtcreator/*.qch
src/tools/gen-cpp-ast/generate-ast src/tools/cplusplus-mkvisitor/cplusplus-mkvisitor
src/tools/mkvisitor/cplusplus0 src/tools/cplusplus-mkvisitor/cplusplus-mkvisitor.exe
src/tools/cplusplus-update-frontend/cplusplus-update-frontend
src/tools/cplusplus-update-frontend/cplusplus-update-frontend.exe
src/tools/qml/qmldump/qmldump src/tools/qml/qmldump/qmldump
src/tools/examplesscanner/examplesscanner src/tools/examplesscanner/examplesscanner
src/tools/valgrindfake/valgrind-fake src/tools/valgrindfake/valgrind-fake
@@ -120,13 +122,15 @@ bin/*.exe
# Tests # Tests
#------ #------
tests/manual/cplusplus-frontend/cplusplus0 tests/manual/cplusplus-frontend/cplusplus-frontend
tests/manual/cplusplus-dump/cplusplus0 tests/manual/cplusplus-frontend/cplusplus-frontend.exe
tests/manual/qml-ast2dot/qml-ast2dot tests/manual/qml-ast2dot/qml-ast2dot
tests/manual/debugger/simple/libsimple_test_plugin.*dylib tests/manual/debugger/simple/libsimple_test_plugin.*dylib
tests/manual/debugger/simple/simple_test_app tests/manual/debugger/simple/simple_test_app
tests/manual/plain-cplusplus/plain-c++ tests/manual/plain-cplusplus/plain-c++
tests/manual/preprocessor/pp tests/manual/preprocessor/pp
tests/tools/cplusplus-ast2png/cplusplus-ast2png
tests/tools/cplusplus-ast2png/cplusplus-ast2png.exe
tests/auto/cplusplus/codegen/tst_codegen tests/auto/cplusplus/codegen/tst_codegen
tests/auto/cplusplus/ast/tst_ast tests/auto/cplusplus/ast/tst_ast
tests/auto/cplusplus/codeformatter/tst_codeformatter tests/auto/cplusplus/codeformatter/tst_codeformatter

View File

@@ -31,7 +31,7 @@
\title Using External Tools \title Using External Tools
You can use external tools directly from \QC. Qt Linguist, You can use external tools directly from \QC. Qt Linguist,
QML Viewer, the QML preview tools, the
default text editor for your system, and the \c sort tool are preconfigured default text editor for your system, and the \c sort tool are preconfigured
for use. You can change their default configurations and configure new for use. You can change their default configurations and configure new
tools. tools.
@@ -59,14 +59,14 @@
\l{http://qt-project.org/doc/qt-4.8/linguist-manual.html} \l{http://qt-project.org/doc/qt-4.8/linguist-manual.html}
{Qt Linguist Manual}. {Qt Linguist Manual}.
\section1 Using QML Viewer \section1 Previewing QML Files
You can preview the current QML document in the QML Viewer. The QML Viewer You can preview the current QML document in the QML Viewer (Qt Quick 1) or
invokes the QML runtime to load QML documents and also includes additional QML Scene (Qt Quick 2). The preview tools enable you to load QML documents
features useful for the development of QML-based applications. for viewing and testing while you are developing an application.
To preview the currently active QML file, select \gui {Tools > External > To preview the currently active QML file, select \gui Tools > \gui External
Qt Quick > Preview (qmlviewer)}. > \gui {Qt Quick} > \gui {Preview (qmlviewer)} or \gui {Preview (qmlscene)}.
\section1 Using External Text Editors \section1 Using External Text Editors

View File

@@ -71,7 +71,8 @@
\o \l{Using External Tools} \o \l{Using External Tools}
You can use external tools directly from \QC. Qt Linguist, You can use external tools directly from \QC. Qt Linguist,
QML Viewer, the default text editor for your system, and the \c sort QML preview tools (QML Viewer and QML Scene), the default text
editor for your system, and the \c sort
tool are preconfigured for use. You can change their default tool are preconfigured for use. You can change their default
configurations and configure new tools. configurations and configure new tools.

View File

@@ -141,8 +141,9 @@
\o Qt Quick UI \o Qt Quick UI
Use a single QML file that contains the main view. You can run Use a single QML file that contains the main view. You can
Qt Quick UI projects in the QML Viewer and you need not build review Qt Quick UI projects in a \l{Previewing QML Files}
{preview tool} and you need not build
them. You do not need to have the development environment them. You do not need to have the development environment
installed on your computer to create and run this type of installed on your computer to create and run this type of
projects projects
@@ -273,7 +274,11 @@
\o Qt resource files, which allow you to store binary files in the \o Qt resource files, which allow you to store binary files in the
application executable application executable
\o QML files, which specify elements in Qt Quick projects \o QML files, which specify elements in Qt Quick projects.
\gui {Qt Quick 1} creates a QML file that imports Qt Quick 1.1 and
\gui {Qt Quick 2} creates a QML file that imports Qt Quick 2.0.
Select \gui {Qt Quick 1} to add files to a Qt Quick 1 application
and \gui {Qt Quick 2} to add files to a Qt Quick 2 application.
\o JavaScript files that you can use to write the application logic in \o JavaScript files that you can use to write the application logic in
Qt Quick projects Qt Quick projects

View File

@@ -59,7 +59,8 @@
develop for platforms that run Qt 5. develop for platforms that run Qt 5.
\o \gui {Qt Quick UI} creates a Qt Quick UI project with a single QML \o \gui {Qt Quick UI} creates a Qt Quick UI project with a single QML
file that contains the main view. You can review Qt Quick UI file that contains the main view. You can review Qt Quick UI
projects in the QML Viewer and you need not build them. You do not projects in a \l{Previewing QML Files}{preview tool} and you need
not build them. You do not
need to have the development environment installed on your need to have the development environment installed on your
computer to create and run this type of project. computer to create and run this type of project.

View File

@@ -127,9 +127,12 @@ macx {
IDE_BIN_PATH = $$IDE_APP_PATH/$${IDE_APP_TARGET}.app/Contents/MacOS IDE_BIN_PATH = $$IDE_APP_PATH/$${IDE_APP_TARGET}.app/Contents/MacOS
copydata = 1 copydata = 1
isEmpty(TIGER_COMPAT_MODE):TIGER_COMPAT_MODE=$$(QTC_TIGER_COMPAT) isEmpty(TIGER_COMPAT_MODE):TIGER_COMPAT_MODE=$$(QTC_TIGER_COMPAT)
isEmpty(TIGER_COMPAT_MODE) { !isEqual(QT_MAJOR_VERSION, 5) {
QMAKE_CXXFLAGS *= -mmacosx-version-min=10.5 # Qt5 doesn't support 10.5, and will set the minimum version correctly to 10.6 or 10.7.
QMAKE_LFLAGS *= -mmacosx-version-min=10.5 isEmpty(TIGER_COMPAT_MODE) {
QMAKE_CXXFLAGS *= -mmacosx-version-min=10.5
QMAKE_LFLAGS *= -mmacosx-version-min=10.5
}
} }
} else { } else {
contains(TEMPLATE, vc.*):vcproj = 1 contains(TEMPLATE, vc.*):vcproj = 1

View File

@@ -7831,7 +7831,7 @@ konnte dem Projekt &apos;%2&apos; nicht hinzugefügt werden.</translation>
</message> </message>
<message> <message>
<source>&amp;Debug</source> <source>&amp;Debug</source>
<translation>&amp;Debuggen</translation> <translation>Deb&amp;uggen</translation>
</message> </message>
<message> <message>
<source>&amp;Start Debugging</source> <source>&amp;Start Debugging</source>

View File

@@ -29,7 +29,7 @@
/* /*
All firstToken/lastToken methods below which have a doxygen comment with All firstToken/lastToken methods below which have a doxygen comment with
\generated in it, will be re-generated when the tool "generate-ast" is run. \generated in it, will be re-generated when the tool "cplusplus-update-frontend" is run.
For methods which are hand-coded, or which should not be changed, make sure that For methods which are hand-coded, or which should not be changed, make sure that
the comment is gone. the comment is gone.

View File

@@ -181,7 +181,11 @@ bool MakeStep::init()
ProcessParameters *pp = processParameters(); ProcessParameters *pp = processParameters();
pp->setMacroExpander(bc->macroExpander()); pp->setMacroExpander(bc->macroExpander());
pp->setEnvironment(bc->environment()); Utils::Environment env = bc->environment();
// Force output to english for the parsers. Do this here and not in the toolchain's
// addToEnvironment() to not screw up the users run environment.
env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
pp->setEnvironment(env);
pp->setWorkingDirectory(bc->buildDirectory()); pp->setWorkingDirectory(bc->buildDirectory());
pp->setCommand(tc ? tc->makeCommand(bc->environment()) : QLatin1String("make")); pp->setCommand(tc ? tc->makeCommand(bc->environment()) : QLatin1String("make"));
pp->setArguments(arguments); pp->setArguments(arguments);

View File

@@ -188,14 +188,13 @@ bool MakeStep::init()
ProcessParameters *pp = processParameters(); ProcessParameters *pp = processParameters();
pp->setMacroExpander(bc->macroExpander()); pp->setMacroExpander(bc->macroExpander());
if (m_useNinja) { Utils::Environment env = bc->environment();
Utils::Environment env = bc->environment(); // Force output to english for the parsers. Do this here and not in the toolchain's
if (!env.value(QLatin1String("NINJA_STATUS")).startsWith(m_ninjaProgressString)) // addToEnvironment() to not screw up the users run environment.
env.set(QLatin1String("NINJA_STATUS"), m_ninjaProgressString + QLatin1String("%o/sec] ")); env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
pp->setEnvironment(env); if (m_useNinja && !env.value(QLatin1String("NINJA_STATUS")).startsWith(m_ninjaProgressString))
} else { env.set(QLatin1String("NINJA_STATUS"), m_ninjaProgressString + QLatin1String("%o/sec] "));
pp->setEnvironment(bc->environment()); pp->setEnvironment(env);
}
pp->setWorkingDirectory(bc->buildDirectory()); pp->setWorkingDirectory(bc->buildDirectory());
pp->setCommand(makeCommand(tc, bc->environment())); pp->setCommand(makeCommand(tc, bc->environment()));
pp->setArguments(arguments); pp->setArguments(arguments);

View File

@@ -1051,5 +1051,4 @@ void CppToolsPlugin::test_completion_enclosing_template_class_data()
completions.append(QLatin1String("int_nested")); completions.append(QLatin1String("int_nested"));
QTest::newRow("case: nested template class with enclosing template class") QTest::newRow("case: nested template class with enclosing template class")
<< code << completions; << code << completions;
} }

View File

@@ -136,7 +136,7 @@ bool Debugger::Internal::interruptProcess(int pID, int engineType, QString *erro
*errorMessage = QLatin1String("DebugBreakProcess failed: ") + Utils::winErrorMessage(GetLastError()); *errorMessage = QLatin1String("DebugBreakProcess failed: ") + Utils::winErrorMessage(GetLastError());
} else { } else {
const QString executable = QCoreApplication::applicationDirPath() + QLatin1String("/win64interrupt.exe"); const QString executable = QCoreApplication::applicationDirPath() + QLatin1String("/win64interrupt.exe");
switch (QProcess::execute(executable + QLatin1Char(' ') + QString::number(pID))) { switch (QProcess::execute(executable, QStringList(QString::number(pID)))) {
case -2: case -2:
*errorMessage = QString::fromLatin1("Cannot start %1. Check src\\tools\\win64interrupt\\win64interrupt.c for more information."). *errorMessage = QString::fromLatin1("Cannot start %1. Check src\\tools\\win64interrupt\\win64interrupt.c for more information.").
arg(QDir::toNativeSeparators(executable)); arg(QDir::toNativeSeparators(executable));

View File

@@ -251,7 +251,8 @@ void QmlInspectorAdapter::engineClientStatusChanged(QmlDebug::ClientStatus statu
BaseEngineDebugClient *client BaseEngineDebugClient *client
= qobject_cast<BaseEngineDebugClient*>(sender()); = qobject_cast<BaseEngineDebugClient*>(sender());
if (status == QmlDebug::Enabled) { if (status == QmlDebug::Enabled && !m_engineClientConnected) {
// We accept the first client that is enabled and reject the others.
QTC_ASSERT(client, return); QTC_ASSERT(client, return);
setActiveEngineClient(client); setActiveEngineClient(client);
} else if (m_engineClientConnected && client == m_engineClient) { } else if (m_engineClientConnected && client == m_engineClient) {

View File

@@ -62,6 +62,7 @@ QmlInspectorAgent::QmlInspectorAgent(DebuggerEngine *engine, QObject *parent)
, m_objectToSelect(-1) , m_objectToSelect(-1)
, m_newObjectsCreated(false) , m_newObjectsCreated(false)
{ {
m_debugIdToIname.insert(-1, QByteArray("inspect"));
connect(debuggerCore()->action(ShowQmlObjectTree), connect(debuggerCore()->action(ShowQmlObjectTree),
SIGNAL(valueChanged(QVariant)), SLOT(updateStatus())); SIGNAL(valueChanged(QVariant)), SLOT(updateStatus()));
m_delayQueryTimer.setSingleShot(true); m_delayQueryTimer.setSingleShot(true);
@@ -452,17 +453,17 @@ void QmlInspectorAgent::onResult(quint32 queryId, const QVariant &value,
} }
if (m_objectTreeQueryIds.contains(queryId)) { if (m_objectTreeQueryIds.contains(queryId)) {
m_objectTreeQueryIds.removeOne(queryId);
if (value.type() == QVariant::List) { if (value.type() == QVariant::List) {
QVariantList objList = value.toList(); QVariantList objList = value.toList();
foreach (QVariant var, objList) { foreach (QVariant var, objList) {
// TODO: check which among the list is the actual // TODO: check which among the list is the actual
// object that needs to be selected. // object that needs to be selected.
insertObjectInTree(qvariant_cast<ObjectReference>(var)); verifyAndInsertObjectInTree(qvariant_cast<ObjectReference>(var));
} }
} else { } else {
insertObjectInTree(qvariant_cast<ObjectReference>(value)); verifyAndInsertObjectInTree(qvariant_cast<ObjectReference>(value));
} }
m_objectTreeQueryIds.removeOne(queryId);
} else if (queryId == m_engineQueryId) { } else if (queryId == m_engineQueryId) {
m_engineQueryId = 0; m_engineQueryId = 0;
QList<EngineReference> engines = qvariant_cast<QList<EngineReference> >(value); QList<EngineReference> engines = qvariant_cast<QList<EngineReference> >(value);
@@ -608,13 +609,13 @@ void QmlInspectorAgent::updateObjectTree(const ContextReference &context)
return; return;
foreach (const ObjectReference & obj, context.objects()) foreach (const ObjectReference & obj, context.objects())
insertObjectInTree(obj); verifyAndInsertObjectInTree(obj);
foreach (const ContextReference &child, context.contexts()) foreach (const ContextReference &child, context.contexts())
updateObjectTree(child); updateObjectTree(child);
} }
void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object) void QmlInspectorAgent::verifyAndInsertObjectInTree(const ObjectReference &object)
{ {
if (debug) if (debug)
qDebug() << __FUNCTION__ << '(' << object << ')'; qDebug() << __FUNCTION__ << '(' << object << ')';
@@ -622,17 +623,56 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object)
if (!object.isValid()) if (!object.isValid())
return; return;
// Find out the correct position in the tree
// Objects are inserted to the tree if they satisfy one of the two conditions.
// Condition 1: Object is a root object i.e. parentId == -1.
// Condition 2: Object has an expanded parent i.e. siblings are known.
// If the two conditions are not met then we push the object to a stack and recursively
// fetch parents till we find a previously expanded parent.
WatchHandler *handler = m_debuggerEngine->watchHandler();
const int parentId = object.parentId();
const int objectDebugId = object.debugId();
if (m_debugIdToIname.contains(parentId)) {
QByteArray parentIname = m_debugIdToIname.value(parentId);
if (parentId != -1 && !handler->isExpandedIName(parentIname)) {
m_objectStack.push(object);
handler->model()->fetchMore(handler->watchDataIndex(parentIname));
return; // recursive
}
insertObjectInTree(object);
} else {
m_objectStack.push(object);
fetchObject(parentId);
return; // recursive
}
if (!m_objectStack.isEmpty()) {
const ObjectReference &top = m_objectStack.top();
// We want to expand only a particular branch and not the whole tree. Hence, we do not
// expand siblings.
if (object.children().contains(top)) {
QByteArray objectIname = m_debugIdToIname.value(objectDebugId);
if (!handler->isExpandedIName(objectIname)) {
handler->model()->fetchMore(handler->watchDataIndex(objectIname));
} else {
verifyAndInsertObjectInTree(m_objectStack.pop());
return; // recursive
}
}
}
}
void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object)
{
if (debug)
qDebug() << __FUNCTION__ << '(' << object << ')';
const int objectDebugId = object.debugId();
const int parentId = parentIdForIname(m_debugIdToIname.value(objectDebugId));
QElapsedTimer timeElapsed; QElapsedTimer timeElapsed;
// sync tree with watchhandler
QList<WatchData> watchData; QList<WatchData> watchData;
int objectDebugId = object.debugId();
// When root items are inserted in the object tree, m_objectTreeQueryIds = 0
if (!m_debugIdToIname.contains(objectDebugId) && m_objectTreeQueryIds.count())
return;
int parentId = parentIdForIname(m_debugIdToIname.value(objectDebugId));
if (debug) if (debug)
timeElapsed.start(); timeElapsed.start();
watchData.append(buildWatchData(object, m_debugIdToIname.value(parentId), true)); watchData.append(buildWatchData(object, m_debugIdToIname.value(parentId), true));
@@ -829,6 +869,7 @@ void QmlInspectorAgent::clearObjectTree()
m_debugIdHash.clear(); m_debugIdHash.clear();
m_debugIdHash.reserve(old_count + 1); m_debugIdHash.reserve(old_count + 1);
m_debugIdToIname.clear(); m_debugIdToIname.clear();
m_debugIdToIname.insert(-1, QByteArray("inspect"));
m_objectStack.clear(); m_objectStack.clear();
// reset only for qt > 4.8.3. // reset only for qt > 4.8.3.
if (m_engineClient->objectName() != QLatin1String(QDECLARATIVE_ENGINE)) if (m_engineClient->objectName() != QLatin1String(QDECLARATIVE_ENGINE))

View File

@@ -110,7 +110,7 @@ private slots:
private: private:
void updateObjectTree(const QmlDebug::ContextReference &context); void updateObjectTree(const QmlDebug::ContextReference &context);
void verifyAndInsertObjectInTree(const QmlDebug::ObjectReference &object);
void insertObjectInTree(const QmlDebug::ObjectReference &result); void insertObjectInTree(const QmlDebug::ObjectReference &result);
void buildDebugIdHashRecursive(const QmlDebug::ObjectReference &ref); void buildDebugIdHashRecursive(const QmlDebug::ObjectReference &ref);

View File

@@ -1809,6 +1809,11 @@ const WatchData *WatchHandler::watchData(const QModelIndex &idx) const
return m_model->watchItem(idx); return m_model->watchItem(idx);
} }
const QModelIndex WatchHandler::watchDataIndex(const QByteArray &iname) const
{
return m_model->watchIndex(m_model->findItem(iname));
}
const WatchData *WatchHandler::findData(const QByteArray &iname) const const WatchData *WatchHandler::findData(const QByteArray &iname) const
{ {
return m_model->findItem(iname); return m_model->findItem(iname);

View File

@@ -85,6 +85,7 @@ public:
void showEditValue(const WatchData &data); void showEditValue(const WatchData &data);
const WatchData *watchData(const QModelIndex &) const; const WatchData *watchData(const QModelIndex &) const;
const QModelIndex watchDataIndex(const QByteArray &iname) const;
const WatchData *findData(const QByteArray &iname) const; const WatchData *findData(const QByteArray &iname) const;
const WatchData *findCppLocalVariable(const QString &name) const; const WatchData *findCppLocalVariable(const QString &name) const;
QString displayForAutoTest(const QByteArray &iname) const; QString displayForAutoTest(const QByteArray &iname) const;

View File

@@ -114,7 +114,11 @@ bool GenericMakeStep::init()
ProcessParameters *pp = processParameters(); ProcessParameters *pp = processParameters();
pp->setMacroExpander(bc->macroExpander()); pp->setMacroExpander(bc->macroExpander());
pp->setWorkingDirectory(bc->buildDirectory()); pp->setWorkingDirectory(bc->buildDirectory());
pp->setEnvironment(bc->environment()); Utils::Environment env = bc->environment();
// Force output to english for the parsers. Do this here and not in the toolchain's
// addToEnvironment() to not screw up the users run environment.
env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
pp->setEnvironment(env);
pp->setCommand(makeCommand(bc->environment())); pp->setCommand(makeCommand(bc->environment()));
pp->setArguments(allArguments()); pp->setArguments(allArguments());

View File

@@ -402,7 +402,7 @@ void BuildManager::nextBuildQueue()
addToOutputWindow(tr("Error while building/deploying project %1 (kit: %2)").arg(projectName, targetName), BuildStep::ErrorOutput); addToOutputWindow(tr("Error while building/deploying project %1 (kit: %2)").arg(projectName, targetName), BuildStep::ErrorOutput);
addToOutputWindow(tr("When executing step '%1'").arg(d->m_currentBuildStep->displayName()), BuildStep::ErrorOutput); addToOutputWindow(tr("When executing step '%1'").arg(d->m_currentBuildStep->displayName()), BuildStep::ErrorOutput);
// NBS TODO fix in qtconcurrent // NBS TODO fix in qtconcurrent
d->m_progressFutureInterface->setProgressValueAndText(d->m_progress*100, tr("Error while building/deploying project %1 (target: %2)").arg(projectName, targetName)); d->m_progressFutureInterface->setProgressValueAndText(d->m_progress*100, tr("Error while building/deploying project %1 (kit: %2)").arg(projectName, targetName));
} }
if (result) if (result)
@@ -502,7 +502,7 @@ bool BuildManager::buildQueueAppend(QList<BuildStep *> steps, QStringList names)
// print something for the user // print something for the user
const QString projectName = bs->project()->displayName(); const QString projectName = bs->project()->displayName();
const QString targetName = bs->target()->displayName(); const QString targetName = bs->target()->displayName();
addToOutputWindow(tr("Error while building/deploying project %1 (target: %2)").arg(projectName, targetName), BuildStep::ErrorOutput); addToOutputWindow(tr("Error while building/deploying project %1 (kit: %2)").arg(projectName, targetName), BuildStep::ErrorOutput);
addToOutputWindow(tr("When executing step '%1'").arg(bs->displayName()), BuildStep::ErrorOutput); addToOutputWindow(tr("When executing step '%1'").arg(bs->displayName()), BuildStep::ErrorOutput);
// disconnect the buildsteps again // disconnect the buildsteps again

View File

@@ -44,6 +44,7 @@ class IOutputParser;
namespace Internal { namespace Internal {
class KitManagerPrivate; class KitManagerPrivate;
class KitModel;
class KitPrivate; class KitPrivate;
} // namespace Internal } // namespace Internal
@@ -110,6 +111,7 @@ private:
Internal::KitPrivate *d; Internal::KitPrivate *d;
friend class KitManager; friend class KitManager;
friend class Internal::KitModel; // needed for setAutoDetected() when cloning kits
}; };
class KitGuard class KitGuard

View File

@@ -89,7 +89,6 @@ QList<Task> SysRootKitInformation::validate(const Kit *k) const
KitConfigWidget *SysRootKitInformation::createConfigWidget(Kit *k) const KitConfigWidget *SysRootKitInformation::createConfigWidget(Kit *k) const
{ {
Q_ASSERT(k);
return new Internal::SysRootInformationConfigWidget(k); return new Internal::SysRootInformationConfigWidget(k);
} }
@@ -184,7 +183,6 @@ void ToolChainKitInformation::fix(Kit *k)
KitConfigWidget *ToolChainKitInformation::createConfigWidget(Kit *k) const KitConfigWidget *ToolChainKitInformation::createConfigWidget(Kit *k) const
{ {
Q_ASSERT(k);
return new Internal::ToolChainInformationConfigWidget(k); return new Internal::ToolChainInformationConfigWidget(k);
} }

View File

@@ -115,7 +115,7 @@ KitManager::KitManager(QObject *parent) :
QObject(parent), QObject(parent),
d(new Internal::KitManagerPrivate()) d(new Internal::KitManagerPrivate())
{ {
Q_ASSERT(!m_instance); QTC_CHECK(!m_instance);
m_instance = this; m_instance = this;
connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()),
@@ -257,7 +257,7 @@ void KitManager::registerKitInformation(KitInformation *ki)
void KitManager::deregisterKitInformation(KitInformation *ki) void KitManager::deregisterKitInformation(KitInformation *ki)
{ {
Q_ASSERT(d->m_informationList.contains(ki)); QTC_CHECK(d->m_informationList.contains(ki));
d->m_informationList.removeAll(ki); d->m_informationList.removeAll(ki);
delete ki; delete ki;
} }

View File

@@ -93,6 +93,9 @@ KitManagerConfigWidget::KitManagerConfigWidget(Kit *k) :
KitManagerConfigWidget::~KitManagerConfigWidget() KitManagerConfigWidget::~KitManagerConfigWidget()
{ {
qDeleteAll(m_widgets);
m_widgets.clear();
delete m_modifiedKit; delete m_modifiedKit;
// Make sure our workingCopy did not get registered somehow: // Make sure our workingCopy did not get registered somehow:
foreach (const Kit *k, KitManager::instance()->kits()) foreach (const Kit *k, KitManager::instance()->kits())
@@ -106,17 +109,18 @@ QString KitManagerConfigWidget::displayName() const
void KitManagerConfigWidget::apply() void KitManagerConfigWidget::apply()
{ {
bool mustSetDefault = m_isDefaultKit;
KitManager *km = KitManager::instance(); KitManager *km = KitManager::instance();
bool mustRegister = false; bool mustRegister = false;
if (!m_kit) { if (!m_kit) {
mustRegister = true; mustRegister = true;
m_kit = new Kit; m_kit = new Kit;
} }
m_kit->copyFrom(m_modifiedKit); m_kit->copyFrom(m_modifiedKit);//m_isDefaultKit is reset in discard() here.
if (mustRegister) if (mustRegister)
km->registerKit(m_kit); km->registerKit(m_kit);
if (m_isDefaultKit) if (mustSetDefault)
km->setDefaultKit(m_kit); km->setDefaultKit(m_kit);
emit dirty(); emit dirty();
} }
@@ -190,7 +194,7 @@ bool KitManagerConfigWidget::configures(Kit *k) const
void KitManagerConfigWidget::setIsDefaultKit(bool d) void KitManagerConfigWidget::setIsDefaultKit(bool d)
{ {
if (m_isDefaultKit != d) if (m_isDefaultKit == d)
return; return;
m_isDefaultKit = d; m_isDefaultKit = d;
emit dirty(); emit dirty();

View File

@@ -76,7 +76,6 @@ public:
// so operate on a temporary list // so operate on a temporary list
QList<KitNode *> tmp = childNodes; QList<KitNode *> tmp = childNodes;
qDeleteAll(tmp); qDeleteAll(tmp);
Q_ASSERT(childNodes.isEmpty());
} }
KitNode *parent; KitNode *parent;
@@ -93,8 +92,6 @@ KitModel::KitModel(QBoxLayout *parentLayout, QObject *parent) :
m_parentLayout(parentLayout), m_parentLayout(parentLayout),
m_defaultNode(0) m_defaultNode(0)
{ {
Q_ASSERT(m_parentLayout);
connect(KitManager::instance(), SIGNAL(kitAdded(ProjectExplorer::Kit*)), connect(KitManager::instance(), SIGNAL(kitAdded(ProjectExplorer::Kit*)),
this, SLOT(addKit(ProjectExplorer::Kit*))); this, SLOT(addKit(ProjectExplorer::Kit*)));
connect(KitManager::instance(), SIGNAL(kitRemoved(ProjectExplorer::Kit*)), connect(KitManager::instance(), SIGNAL(kitRemoved(ProjectExplorer::Kit*)),
@@ -196,7 +193,6 @@ Qt::ItemFlags KitModel::flags(const QModelIndex &index) const
return 0; return 0;
KitNode *node = static_cast<KitNode *>(index.internalPointer()); KitNode *node = static_cast<KitNode *>(index.internalPointer());
Q_ASSERT(node);
if (!node->widget) if (!node->widget)
return Qt::ItemIsEnabled; return Qt::ItemIsEnabled;
@@ -216,7 +212,6 @@ Kit *KitModel::kit(const QModelIndex &index)
if (!index.isValid()) if (!index.isValid())
return 0; return 0;
KitNode *node = static_cast<KitNode *>(index.internalPointer()); KitNode *node = static_cast<KitNode *>(index.internalPointer());
Q_ASSERT(node);
return node->widget->workingCopy(); return node->widget->workingCopy();
} }
@@ -231,7 +226,6 @@ void KitModel::setDefaultKit(const QModelIndex &index)
if (!index.isValid()) if (!index.isValid())
return; return;
KitNode *node = static_cast<KitNode *>(index.internalPointer()); KitNode *node = static_cast<KitNode *>(index.internalPointer());
Q_ASSERT(node);
if (node->widget) if (node->widget)
setDefaultNode(node); setDefaultNode(node);
} }
@@ -246,7 +240,6 @@ KitManagerConfigWidget *KitModel::widget(const QModelIndex &index)
if (!index.isValid()) if (!index.isValid())
return 0; return 0;
KitNode *node = static_cast<KitNode *>(index.internalPointer()); KitNode *node = static_cast<KitNode *>(index.internalPointer());
Q_ASSERT(node);
return node->widget; return node->widget;
} }
@@ -284,10 +277,11 @@ void KitModel::apply()
Q_ASSERT(!n->parent); Q_ASSERT(!n->parent);
n->widget->removeKit(); n->widget->removeKit();
} }
Q_ASSERT(m_toRemoveList.isEmpty());
// Update kits: // Update kits:
foreach (KitNode *n, m_manualRoot->childNodes) { nodes = m_autoRoot->childNodes; // These can be dirty due to being made default!
nodes.append(m_manualRoot->childNodes);
foreach (KitNode *n, nodes) {
Q_ASSERT(n); Q_ASSERT(n);
Q_ASSERT(n->widget); Q_ASSERT(n->widget);
if (n->widget->isDirty()) { if (n->widget->isDirty()) {
@@ -330,7 +324,9 @@ Kit *KitModel::markForAddition(Kit *baseKit)
KitNode *node = createNode(m_manualRoot, 0); KitNode *node = createNode(m_manualRoot, 0);
if (baseKit) { if (baseKit) {
Kit *k = node->widget->workingCopy(); Kit *k = node->widget->workingCopy();
KitGuard g(k);
k->copyFrom(baseKit); k->copyFrom(baseKit);
k->setAutoDetected(false); // Make sure we have a manual kit!
k->setDisplayName(tr("Clone of %1").arg(k->displayName())); k->setDisplayName(tr("Clone of %1").arg(k->displayName()));
} }

View File

@@ -94,7 +94,6 @@ QWidget *KitOptionsPage::createPage(QWidget *parent)
QVBoxLayout *verticalLayout = new QVBoxLayout(m_configWidget); QVBoxLayout *verticalLayout = new QVBoxLayout(m_configWidget);
verticalLayout->addLayout(horizontalLayout); verticalLayout->addLayout(horizontalLayout);
Q_ASSERT(!m_model);
m_model = new Internal::KitModel(verticalLayout); m_model = new Internal::KitModel(verticalLayout);
connect(m_model, SIGNAL(kitStateChanged()), this, SLOT(updateState())); connect(m_model, SIGNAL(kitStateChanged()), this, SLOT(updateState()));
verticalLayout->setStretch(0, 1); verticalLayout->setStretch(0, 1);

View File

@@ -467,19 +467,19 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect()
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, version),
fi.absoluteFilePath(), QLatin1String("/x86"), true)); fi.absoluteFilePath(), QLatin1String("/x86"), true));
// Add all platforms // Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, version),
fi.absoluteFilePath(), QLatin1String("/amd64"), true)); fi.absoluteFilePath(), QLatin1String("/x64"), true));
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_amd64, version),
fi.absoluteFilePath(), QLatin1String("/x86_amd64"), true)); fi.absoluteFilePath(), QLatin1String("/x64"), true));
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, version),
fi.absoluteFilePath(), QLatin1String("/ia64"), true)); fi.absoluteFilePath(), QLatin1String("/ia64"), true));
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86_ia64, version),
fi.absoluteFilePath(), QLatin1String("/x86_ia64"), true)); fi.absoluteFilePath(), QLatin1String("/ia64"), true));
// Make sure the default is front. // Make sure the default is front.
if (folder == defaultSdkPath) if (folder == defaultSdkPath)
results = tmp + results; results = tmp + results;

View File

@@ -159,9 +159,15 @@ bool DebuggerRunConfigurationAspect::useCppDebugger() const
static bool isQtQuickAppProject(Project *project) static bool isQtQuickAppProject(Project *project)
{ {
const QString filePath = project->projectDirectory() const QString projectDirectory = project->projectDirectory();
// Qt Quick 1 wizard generated file
const QString qq1FilePath = projectDirectory
+ QLatin1String("/qmlapplicationviewer/qmlapplicationviewer.pri"); + QLatin1String("/qmlapplicationviewer/qmlapplicationviewer.pri");
return project->files(Project::ExcludeGeneratedFiles).contains(filePath); // Qt Quick 2 wizard generated file
const QString qq2FilePath = projectDirectory
+ QLatin1String("/qtquick2applicationviewer/qtquick2applicationviewer.pri");
const QStringList projectFiles = project->files(Project::ExcludeGeneratedFiles);
return projectFiles.contains(qq1FilePath) || projectFiles.contains(qq2FilePath);
} }
bool DebuggerRunConfigurationAspect::useQmlDebugger() const bool DebuggerRunConfigurationAspect::useQmlDebugger() const

View File

@@ -210,21 +210,23 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV
} }
} else { } else {
QMessageBox::warning(0, tr("Cannot Start QML Puppet Executable"), if (!hasQtQuick2(m_nodeInstanceView.data()))
tr("The executable of the QML Puppet process (%1) cannot be started. " QMessageBox::warning(0, tr("Cannot Start QML Puppet Executable"),
"Please check your installation. " tr("The executable of the QML Puppet process (%1) cannot be started. "
"QML Puppet is a process which runs in the background to render the items."). "Please check your installation. "
arg(applicationPath)); "QML Puppet is a process which runs in the background to render the items.").
arg(applicationPath));
} }
m_localServer->close(); m_localServer->close();
} else { } else {
QMessageBox::warning(0, tr("Cannot Find QML Puppet Executable"), if (!hasQtQuick2(m_nodeInstanceView.data()))
tr("The executable of the QML Puppet process (%1) cannot be found. " QMessageBox::warning(0, tr("Cannot Find QML Puppet Executable"),
"Please check your installation. " tr("The executable of the QML Puppet process (%1) cannot be found. "
"QML Puppet is a process which runs in the background to render the items."). "Please check your installation. "
arg(applicationPath)); "QML Puppet is a process which runs in the background to render the items.").
arg(applicationPath));
} }
} }

View File

@@ -79,7 +79,7 @@ Core::BaseFileWizardParameters QmlProjectApplicationWizard::parameters()
"QML file that contains the main view.\n\n" "QML file that contains the main view.\n\n"
"You can review Qt Quick UI projects in the QML Viewer and you need not build them. " "You can review Qt Quick UI projects in the QML Viewer and you need not build them. "
"You do not need to have the development environment installed " "You do not need to have the development environment installed "
"on your computer to create and run this type of project.\n\nRequires <b>Qt 4.7.4</b> or newer.")); "on your computer to create and run this type of projects.\n\nRequires <b>Qt 5.0</b> or newer."));
parameters.setCategory(QLatin1String(ProjectExplorer::Constants::QT_APPLICATION_WIZARD_CATEGORY)); parameters.setCategory(QLatin1String(ProjectExplorer::Constants::QT_APPLICATION_WIZARD_CATEGORY));
parameters.setDisplayCategory(QT_TRANSLATE_NOOP("ProjectExplorer", "Qt Application")); parameters.setDisplayCategory(QT_TRANSLATE_NOOP("ProjectExplorer", "Qt Application"));
return parameters; return parameters;
@@ -119,8 +119,7 @@ Core::GeneratedFiles QmlProjectApplicationWizard::generateFiles(const QWizard *w
QTextStream out(&contents); QTextStream out(&contents);
out out
<< "// import QtQuick 1.0 // to target Maemo 5" << endl << "import QtQuick 2.0" << endl
<< "import QtQuick 1.1" << endl
<< endl << endl
<< "Rectangle {" << endl << "Rectangle {" << endl
<< " width: 360" << endl << " width: 360" << endl

View File

@@ -203,9 +203,12 @@ QStringList QMakeStep::deducedArguments()
if (!version->needsQmlDebuggingLibrary()) { if (!version->needsQmlDebuggingLibrary()) {
// This Qt version has the QML debugging services built in, however // This Qt version has the QML debugging services built in, however
// they still need to be enabled at compile time // they still need to be enabled at compile time
arguments << (version->qtVersion().majorVersion >= 5 ? // TODO: For Qt5, we can pass both arguments as there can be Qt Quick 1/2 projects.
QLatin1String(Constants::QMAKEVAR_DECLARATIVE_DEBUG5) : // Currently there is no support for debugging multiple engines.
QLatin1String(Constants::QMAKEVAR_DECLARATIVE_DEBUG4)); arguments << QLatin1String(Constants::QMAKEVAR_QUICK1_DEBUG);
if (version->qtVersion().majorVersion >= 5) {
arguments << QLatin1String(Constants::QMAKEVAR_QUICK2_DEBUG);
}
} else { } else {
const QString qmlDebuggingHelperLibrary = version->qmlDebuggingHelperLibrary(true); const QString qmlDebuggingHelperLibrary = version->qmlDebuggingHelperLibrary(true);
if (!qmlDebuggingHelperLibrary.isEmpty()) { if (!qmlDebuggingHelperLibrary.isEmpty()) {

View File

@@ -458,8 +458,8 @@ bool Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
for (QtcProcess::ArgIterator ait(args); ait.next(); ) { for (QtcProcess::ArgIterator ait(args); ait.next(); ) {
const QString arg = ait.value(); const QString arg = ait.value();
if (arg.contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)) if (arg.contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH))
|| arg.contains(QLatin1String(Constants::QMAKEVAR_DECLARATIVE_DEBUG4)) || arg.contains(QLatin1String(Constants::QMAKEVAR_QUICK1_DEBUG))
|| arg.contains(QLatin1String(Constants::QMAKEVAR_DECLARATIVE_DEBUG5))) { || arg.contains(QLatin1String(Constants::QMAKEVAR_QUICK2_DEBUG))) {
ait.deleteArg(); ait.deleteArg();
removedArgument = true; removedArgument = true;
} }

View File

@@ -89,8 +89,8 @@ const char ICON_HTML5_APP[] = ":/wizards/images/html5app.png";
// Env variables // Env variables
const char QMAKEVAR_QMLJSDEBUGGER_PATH[] = "QMLJSDEBUGGER_PATH"; const char QMAKEVAR_QMLJSDEBUGGER_PATH[] = "QMLJSDEBUGGER_PATH";
const char QMAKEVAR_DECLARATIVE_DEBUG4[] = "CONFIG+=declarative_debug"; const char QMAKEVAR_QUICK1_DEBUG[] = "CONFIG+=declarative_debug";
const char QMAKEVAR_DECLARATIVE_DEBUG5[] = "CONFIG+=qml_debug"; const char QMAKEVAR_QUICK2_DEBUG[] = "CONFIG+=qml_debug";
// Unconfigured Panel // Unconfigured Panel
const char UNCONFIGURED_PANEL_PAGE_ID[] = "UnconfiguredPanel"; const char UNCONFIGURED_PANEL_PAGE_ID[] = "UnconfiguredPanel";

View File

@@ -135,7 +135,7 @@ void QtQuickAppWizard::createInstances(ExtensionSystem::IPlugin *plugin)
QList<Core::BaseFileWizardParameters> list; QList<Core::BaseFileWizardParameters> list;
Core::BaseFileWizardParameters parameter; Core::BaseFileWizardParameters parameter;
const QString basicDescription = tr("Creates a Qt Quick application project that can contain " const QString basicDescription = tr("Creates a Qt Quick 1 application project that can contain "
"both QML and C++ code and includes a QDeclarativeView.\n\n"); "both QML and C++ code and includes a QDeclarativeView.\n\n");
Core::FeatureSet basicFeatures; Core::FeatureSet basicFeatures;
@@ -151,7 +151,7 @@ void QtQuickAppWizard::createInstances(ExtensionSystem::IPlugin *plugin)
parameter = base; parameter = base;
parameter.setDisplayName(tr("Qt Quick 2 Application (Built-in Elements)")); parameter.setDisplayName(tr("Qt Quick 2 Application (Built-in Elements)"));
parameter.setDescription(tr("Creates a Qt Quick application project that can contain " parameter.setDescription(tr("Creates a Qt Quick 2 application project that can contain "
"both QML and C++ code and includes a QQuickView.\n\n" "both QML and C++ code and includes a QQuickView.\n\n"
"The built-in elements in the QtQuick 2 namespace allow " "The built-in elements in the QtQuick 2 namespace allow "
"you to write cross-platform applications with " "you to write cross-platform applications with "
@@ -160,7 +160,7 @@ void QtQuickAppWizard::createInstances(ExtensionSystem::IPlugin *plugin)
list << parameter; list << parameter;
parameter = base; parameter = base;
parameter.setDisplayName(tr("Qt Quick Application for MeeGo Harmattan")); parameter.setDisplayName(tr("Qt Quick 1 Application for MeeGo Harmattan"));
parameter.setDescription(basicDescription + tr("The Qt Quick Components for MeeGo Harmattan are " parameter.setDescription(basicDescription + tr("The Qt Quick Components for MeeGo Harmattan are "
"a set of ready-made components that are designed " "a set of ready-made components that are designed "
"with specific native appearance for the MeeGo Harmattan " "with specific native appearance for the MeeGo Harmattan "
@@ -171,7 +171,7 @@ void QtQuickAppWizard::createInstances(ExtensionSystem::IPlugin *plugin)
list << parameter; list << parameter;
parameter = base; parameter = base;
parameter.setDisplayName(tr("Qt Quick Application (from Existing QML File)")); parameter.setDisplayName(tr("Qt Quick 1 Application (from Existing QML File)"));
parameter.setDescription(basicDescription + tr("Creates a deployable Qt Quick application from " parameter.setDescription(basicDescription + tr("Creates a deployable Qt Quick application from "
"existing QML files. All files and directories that " "existing QML files. All files and directories that "
"reside in the same directory as the main .qml file " "reside in the same directory as the main .qml file "

View File

@@ -1189,49 +1189,69 @@ bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Utils::Env
return BaseQtVersion::queryQMakeVariables(binary, env, versionInfo, &qmakeIsExecutable); return BaseQtVersion::queryQMakeVariables(binary, env, versionInfo, &qmakeIsExecutable);
} }
bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Utils::Environment &env, static QByteArray runQmakeQuery(const FileName &binary, const Environment &env,
QHash<QString, QString> *versionInfo, bool *qmakeIsExecutable) bool *isExecutable)
{ {
const int timeOutMS = 30000; // Might be slow on some machines. const int timeOutMS = 30000; // Might be slow on some machines.
QProcess process;
process.setEnvironment(env.toStringList());
process.start(binary.toString(), QStringList(QLatin1String("-query")), QIODevice::ReadOnly);
if (!process.waitForStarted()) {
qWarning("Cannot start '%s': %s", qPrintable(binary.toUserOutput()), qPrintable(process.errorString()));
*isExecutable = false;
return QByteArray();
}
if (!process.waitForFinished(timeOutMS)) {
SynchronousProcess::stopProcess(process);
*isExecutable = true;
qWarning("Timeout running '%s' (%dms).", qPrintable(binary.toUserOutput()), timeOutMS);
return QByteArray();
}
if (process.exitStatus() != QProcess::NormalExit) {
qWarning("'%s' crashed.", qPrintable(binary.toUserOutput()));
*isExecutable = false;
return QByteArray();
}
*isExecutable = true;
return process.readAllStandardOutput();
}
bool BaseQtVersion::queryQMakeVariables(const FileName &binary, const Environment &env,
QHash<QString, QString> *versionInfo, bool *qmakeIsExecutable)
{
const QFileInfo qmake = binary.toFileInfo(); const QFileInfo qmake = binary.toFileInfo();
*qmakeIsExecutable = qmake.exists() && qmake.isExecutable() && !qmake.isDir(); *qmakeIsExecutable = qmake.exists() && qmake.isExecutable() && !qmake.isDir();
if (!*qmakeIsExecutable) if (!*qmakeIsExecutable)
return false; return false;
QProcess process; QByteArray output;
Environment qmakeEnv = env; output = runQmakeQuery(binary, env, qmakeIsExecutable);
if (HostOsInfo::isWindowsHost()) { if (output.isNull() && !qmakeIsExecutable) {
// Add tool chain environment. This is necessary for non-static qmakes e.g. using mingw on windows // Note: Don't rerun if we were able to execute the binary before.
// We can not just add all the environments of all tool chains since that will make PATH too long
// which in turn will trigger a crash when parsing the results of vcvars.bat of MSVC. // Try running qmake with all kinds of tool chains set up in the environment.
// This is required to make non-static qmakes work on windows where every tool chain
// tries to be incompatible with any other.
QList<ProjectExplorer::Abi> abiList = ProjectExplorer::Abi::abisOfBinary(binary); QList<ProjectExplorer::Abi> abiList = ProjectExplorer::Abi::abisOfBinary(binary);
QList<ProjectExplorer::ToolChain *> tcList = ProjectExplorer::ToolChainManager::instance()->toolChains(); QList<ProjectExplorer::ToolChain *> tcList = ProjectExplorer::ToolChainManager::instance()->toolChains();
foreach (ProjectExplorer::ToolChain *tc, tcList) { foreach (ProjectExplorer::ToolChain *tc, tcList) {
if (abiList.contains(tc->targetAbi())) if (!abiList.contains(tc->targetAbi()))
tc->addToEnvironment(qmakeEnv); continue;
Environment realEnv = env;
tc->addToEnvironment(realEnv);
output = runQmakeQuery(binary, realEnv, qmakeIsExecutable);
if (qmakeIsExecutable)
break;
} }
} }
process.setEnvironment(qmakeEnv.toStringList()); if (output.isNull())
process.start(qmake.absoluteFilePath(), QStringList(QLatin1String("-query")), QIODevice::ReadOnly); return false;
if (!process.waitForStarted()) {
*qmakeIsExecutable = false;
qWarning("Cannot start '%s': %s", qPrintable(binary.toUserOutput()), qPrintable(process.errorString()));
return false;
}
if (!process.waitForFinished(timeOutMS)) {
SynchronousProcess::stopProcess(process);
qWarning("Timeout running '%s' (%dms).", qPrintable(binary.toUserOutput()), timeOutMS);
return false;
}
if (process.exitStatus() != QProcess::NormalExit) {
*qmakeIsExecutable = false;
qWarning("'%s' crashed.", qPrintable(binary.toUserOutput()));
return false;
}
QByteArray output = process.readAllStandardOutput();
QTextStream stream(&output); QTextStream stream(&output);
while (!stream.atEnd()) { while (!stream.atEnd()) {
const QString line = stream.readLine(); const QString line = stream.readLine();

View File

@@ -40,6 +40,9 @@
#include <qtsupport/qtversionmanager.h> #include <qtsupport/qtversionmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/environment.h>
#include <projectexplorer/kitmanager.h>
#include <qtsupport/qtkitinformation.h>
#include <algorithm> #include <algorithm>
using QtSupport::QtVersionManager; using QtSupport::QtVersionManager;
@@ -309,6 +312,16 @@ QStringList ExamplesListModel::exampleSources(QString *examplesFallback, QString
QStringList sources; QStringList sources;
QString resourceDir = Core::ICore::resourcePath() + QLatin1String("/welcomescreen/"); QString resourceDir = Core::ICore::resourcePath() + QLatin1String("/welcomescreen/");
// overriding examples with a custom XML file
QString exampleFileEnvKey = QLatin1String("QTC_EXAMPLE_FILE");
if (Utils::Environment::systemEnvironment().hasKey(exampleFileEnvKey)) {
QString filePath = Utils::Environment::systemEnvironment().value(exampleFileEnvKey);
if (filePath.endsWith(QLatin1String(".xml")) && QFileInfo(filePath).exists()) {
sources.append(filePath);
return sources;
}
}
// Qt Creator shipped tutorials // Qt Creator shipped tutorials
sources << (resourceDir + QLatin1String("/qtcreator_tutorials.xml")); sources << (resourceDir + QLatin1String("/qtcreator_tutorials.xml"));
@@ -331,11 +344,38 @@ QStringList ExamplesListModel::exampleSources(QString *examplesFallback, QString
QString potentialExamplesFallback; QString potentialExamplesFallback;
QString potentialDemosFallback; QString potentialDemosFallback;
QString potentialSourceFallback; QString potentialSourceFallback;
bool potentialFallbackHasDeclarative = false; // we prefer Qt's with declarative as fallback
const QStringList pattern(QLatin1String("*.xml")); const QStringList pattern(QLatin1String("*.xml"));
// prioritize default qt version
QtVersionManager *versionManager = QtVersionManager::instance(); QtVersionManager *versionManager = QtVersionManager::instance();
foreach (BaseQtVersion *version, versionManager->validVersions()) { QList <BaseQtVersion *> qtVersions = versionManager->validVersions();
ProjectExplorer::Kit *defaultKit = ProjectExplorer::KitManager::instance()->defaultKit();
BaseQtVersion *defaultVersion = QtKitInformation::qtVersion(defaultKit);
if (defaultVersion && qtVersions.contains(defaultVersion))
qtVersions.move(qtVersions.indexOf(defaultVersion), 0);
foreach (BaseQtVersion *version, qtVersions) {
// qt5 with examples OR demos manifest
if (version->qtVersion().majorVersion == 5 && (version->hasExamples() || version->hasDemos())) {
// examples directory in Qt5 is under the qtbase submodule,
// search other submodule directories for further manifest files
QDir qt5docPath = QDir(version->documentationPath());
const QStringList examplesPattern(QLatin1String("examples-manifest.xml"));
const QStringList demosPattern(QLatin1String("demos-manifest.xml"));
QFileInfoList fis;
foreach (QFileInfo subDir, qt5docPath.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
if (version->hasExamples())
fis << QDir(subDir.absoluteFilePath()).entryInfoList(examplesPattern);
if (version->hasDemos())
fis << QDir(subDir.absoluteFilePath()).entryInfoList(demosPattern);
}
if (!fis.isEmpty()) {
foreach (const QFileInfo &fi, fis)
sources.append(fi.filePath());
return sources;
}
}
QFileInfoList fis; QFileInfoList fis;
if (version->hasExamples()) if (version->hasExamples())
fis << QDir(version->examplesPath()).entryInfoList(pattern); fis << QDir(version->examplesPath()).entryInfoList(pattern);
@@ -346,13 +386,9 @@ QStringList ExamplesListModel::exampleSources(QString *examplesFallback, QString
sources.append(fi.filePath()); sources.append(fi.filePath());
return sources; return sources;
} }
// check if this Qt version would be the preferred fallback, Qt 4 only // check if this Qt version would be the preferred fallback, Qt 4 only
if (version->qtVersion().majorVersion == 4 && version->hasExamples() && version->hasDemos()) { // cached, so no performance hit if (version->qtVersion().majorVersion == 4 && version->hasExamples() && version->hasDemos()) { // cached, so no performance hit
bool hasDeclarative = QDir(version->examplesPath() + QLatin1String("/declarative")).exists(); if (potentialExamplesFallback.isEmpty()) {
if (potentialExamplesFallback.isEmpty()
|| (!potentialFallbackHasDeclarative && hasDeclarative)) {
potentialFallbackHasDeclarative = hasDeclarative;
potentialExamplesFallback = version->examplesPath(); potentialExamplesFallback = version->examplesPath();
potentialDemosFallback = version->demosPath(); potentialDemosFallback = version->demosPath();
potentialSourceFallback = version->sourcePath().toString(); potentialSourceFallback = version->sourcePath().toString();

View File

@@ -44,6 +44,8 @@
#include <Overview.h> #include <Overview.h>
#include <LookupContext.h> #include <LookupContext.h>
#include "cplusplus-tools-utils.h"
#include <QFile> #include <QFile>
#include <QList> #include <QList>
#include <QCoreApplication> #include <QCoreApplication>
@@ -422,35 +424,65 @@ protected:
} }
}; };
void printUsage()
{
std::cout << "Usage: " << qPrintable(QFileInfo(qApp->arguments().at(0)).fileName())
<< " [-v] [path to AST.h]\n\n"
<< "Print a visitor class based on AST.h to stdout.\n\n";
const QString defaulPath = QFileInfo(PATH_AST_H).canonicalFilePath();
std::cout << "Default path: " << qPrintable(defaulPath) << '.' << "\n";
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QStringList args = app.arguments();
args.removeFirst();
QStringList files = app.arguments(); bool optionVerbose = false;
files.removeFirst();
foreach (const QString &fileName, files) { // Process options & arguments
QFile file(fileName); if (args.contains("-v")) {
if (! file.open(QFile::ReadOnly)) optionVerbose = true;
continue; args.removeOne("-v");
const QByteArray source = file.readAll();
file.close();
Document::Ptr doc = Document::create(fileName);
//doc->control()->setDiagnosticClient(0);
doc->setUtf8Source(source);
doc->parse();
doc->translationUnit()->blockErrors(true);
doc->check();
Snapshot snapshot;
snapshot.insert(doc);
LookupContext context(doc, snapshot);
MkVisitor mkVisitor(context);
} }
const bool helpRequested = args.contains("-h") || args.contains("-help");
if (helpRequested || args.count() >= 2) {
printUsage();
return helpRequested ? EXIT_SUCCESS : EXIT_FAILURE;
}
// Run the preprocessor
QString fileName = PATH_AST_H;
if (!args.isEmpty())
fileName = args.first();
const QString fileNamePreprocessed = fileName + QLatin1String(".preprocessed");
CplusplusToolsUtils::SystemPreprocessor preprocessor(optionVerbose);
preprocessor.preprocessFile(fileName, fileNamePreprocessed);
QFile file(fileNamePreprocessed);
if (! file.open(QFile::ReadOnly)) {
std::cerr << "Error: Could not open file \"" << qPrintable(file.fileName()) << "\"."
<< std::endl;
return EXIT_FAILURE;
}
const QByteArray source = file.readAll();
file.close();
Document::Ptr doc = Document::create(fileName);
//doc->control()->setDiagnosticClient(0);
doc->setUtf8Source(source);
doc->parse();
doc->translationUnit()->blockErrors(true);
doc->check();
Snapshot snapshot;
snapshot.insert(doc);
LookupContext context(doc, snapshot);
MkVisitor mkVisitor(context);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@@ -0,0 +1,13 @@
QT = core gui
macx:CONFIG -= app_bundle
win32:CONFIG += console
TEMPLATE = app
TARGET = cplusplus-mkvisitor
DESTDIR = ./
include(../../../qtcreator.pri)
include(../../libs/cplusplus/cplusplus-lib.pri)
include(../../../src/tools/cplusplus-tools-utils/cplusplus-tools-utils.pri)
DEFINES += PATH_AST_H=\\\"$$PWD/../../libs/3rdparty/cplusplus/AST.h\\\"
SOURCES += cplusplus-mkvisitor.cpp

View File

@@ -0,0 +1,140 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "cplusplus-tools-utils.h"
#include "environment.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QProcess>
namespace CplusplusToolsUtils {
QString portableExecutableName(const QString &executable)
{
#if defined(Q_OS_WIN)
return executable + QLatin1String(".exe");
#else
return executable;
#endif
}
void executeCommand(const QString &command, const QStringList &arguments, const QString &outputFile,
bool verbose)
{
QTextStream out(stderr);
if (command.isEmpty()) {
out << "Error: " << Q_FUNC_INFO << "Got empty command to execute." << endl;
exit(EXIT_FAILURE);
}
const QString fullCommand = command + QLatin1Char(' ') + arguments.join(QLatin1String(" "));
if (verbose)
out << "Executing: " << fullCommand << endl;
QProcess process;
if (!outputFile.isEmpty())
process.setStandardOutputFile(outputFile, QIODevice::Truncate);
process.start(command, arguments);
if (!process.waitForStarted()) {
out << QString("Error: Process \"%1\" did not start within timeout: %2.")
.arg(fullCommand, process.errorString())
<< endl;
exit(EXIT_FAILURE);
}
if (!process.waitForFinished()) {
if (!verbose)
out << process.readAll() << endl;
out << QString("Error: Process \"%1\" did not finish within timeout.").arg(fullCommand)
<< endl;
exit(EXIT_FAILURE);
}
const int exitCode = process.exitCode();
if (exitCode != 0) {
out << process.readAllStandardError() << endl;
out << QString("Error: Process \"%1\" finished with non zero exit value %2")
.arg(fullCommand, exitCode) << endl;
exit(EXIT_FAILURE);
}
}
SystemPreprocessor::SystemPreprocessor(bool verbose)
: m_verbose(verbose)
{
m_knownCompilers[portableExecutableName("gcc")]
= QLatin1String("-DCPLUSPLUS_WITHOUT_QT -U__BLOCKS__ -xc++ -E -include");
m_knownCompilers[portableExecutableName("cl")]
= QLatin1String("/DCPLUSPLUS_WITHOUT_QT /U__BLOCKS__ /TP /E /I . /FI");
QMapIterator<QString, QString> i(m_knownCompilers);
while (i.hasNext()) {
i.next();
const QString executablePath
= Utils::Environment::systemEnvironment().searchInPath(i.key());
if (!executablePath.isEmpty()) {
m_compiler = i.key();
m_compilerArguments = i.value().split(QLatin1String(" "), QString::SkipEmptyParts);
m_compilerArguments
<< QDir::toNativeSeparators(QLatin1String(PATH_PREPROCESSOR_CONFIG));
break;
}
}
}
void SystemPreprocessor::check() const
{
QTextStream out(stderr);
if (!QFile::exists(PATH_PREPROCESSOR_CONFIG)) {
out << QString("Error: File \"%1\" does not exist.").arg(PATH_PREPROCESSOR_CONFIG) << endl;
exit(EXIT_FAILURE);
}
if (m_compiler.isEmpty()) {
const QString triedCompilers
= QStringList(m_knownCompilers.keys()).join(QLatin1String(", "));
out << QString("Error: No compiler found. Tried %1.").arg(triedCompilers) << endl;
exit(EXIT_FAILURE);
}
}
void SystemPreprocessor::preprocessFile(const QString &inputFile, const QString &outputFile) const
{
check();
if (!QFile::exists(inputFile)) {
QTextStream out(stderr);
out << QString("Error: File \"%1\" does not exist.").arg(inputFile) << endl;
exit(EXIT_FAILURE);
}
const QStringList arguments = QStringList(m_compilerArguments)
<< QDir::toNativeSeparators(inputFile);
executeCommand(m_compiler, arguments, outputFile, m_verbose);
}
} // namespace

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CPLUSPLUSTOOLSUTILS_H
#define CPLUSPLUSTOOLSUTILS_H
#include <QString>
#include <QStringList>
#include <QMap>
namespace CplusplusToolsUtils {
QString portableExecutableName(const QString &executable);
void executeCommand(const QString &command, const QStringList &arguments, const QString &outputFile,
bool verbose = false);
// Preprocess a file by calling an external compiler in preprocessor mode (-E, /E).
class SystemPreprocessor
{
public:
SystemPreprocessor(bool verbose = false);
void preprocessFile(const QString &inputFile, const QString &outputFile) const;
private:
void check() const;
QMap<QString, QString> m_knownCompilers;
QString m_compiler; // Compiler that will be called in preprocessor mode
QStringList m_compilerArguments;
bool m_verbose;
};
} // namespace
#endif // CPLUSPLUSTOOLSUTILS_H

View File

@@ -0,0 +1,13 @@
DEPENDPATH += $$PWD
INCLUDEPATH += $$PWD $$PWD/../../libs/utils
DEFINES += PATH_PREPROCESSOR_CONFIG=\\\"$$PWD/pp-configuration.inc\\\"
DEFINES += QTCREATOR_UTILS_STATIC_LIB
HEADERS += \
$$PWD/cplusplus-tools-utils.h \
$$PWD/../../libs/utils/environment.h
SOURCES += \
$$PWD/cplusplus-tools-utils.cpp \
$$PWD/../../libs/utils/environment.cpp

View File

@@ -1,15 +1,17 @@
#define __extension__ #define __extension__
#define __context__ #define __context__
#define __range__ #define __range__
#define __asm(a...) #if !defined(_WIN32) && !defined(_WIN64)
#define __asm__(a...) # define __asm(a...)
# define __asm__(a...)
# define __stdcall
# define __fastcall
#endif
#define restrict #define restrict
#define __restrict #define __restrict
#define __restrict__ #define __restrict__
// #define __weak // #define __weak
#define __builtin_va_arg(a,b) ((b)0) #define __builtin_va_arg(a,b) ((b)0)
#define __stdcall
#define __fastcall
#define __imag__ #define __imag__
#define __real__ #define __real__
#define __complex__ #define __complex__

View File

@@ -91,12 +91,21 @@ static const char generatedHeader[] =
"// W A R N I N G\n" "// W A R N I N G\n"
"// -------------\n" "// -------------\n"
"//\n" "//\n"
"// This file is automatically generated.\n" "// This file is automatically generated by \"cplusplus-update-frontend\".\n"
"// Changes will be lost.\n" "// Changes will be lost.\n"
"//\n" "//\n"
"\n" "\n"
; ;
static void closeAndPrintFilePath(QFile &file)
{
if (file.isOpen()) {
const QString filePath = QFileInfo(file).canonicalFilePath();
std::cout << QDir::toNativeSeparators(filePath).toLatin1().constData() << std::endl;
file.close();
}
}
class ASTNodes class ASTNodes
{ {
public: public:
@@ -226,6 +235,8 @@ public:
"using namespace CPlusPlus;\n" << endl; "using namespace CPlusPlus;\n" << endl;
accept(ast); accept(ast);
closeAndPrintFilePath(file);
} }
protected: protected:
@@ -354,7 +365,6 @@ public:
QTextStream output(&file); QTextStream output(&file);
out = &output; out = &output;
*out << copyrightHeader << generatedHeader << *out << copyrightHeader << generatedHeader <<
"\n" "\n"
"#include \"AST.h\"\n" "#include \"AST.h\"\n"
@@ -363,6 +373,8 @@ public:
"using namespace CPlusPlus;\n" << endl; "using namespace CPlusPlus;\n" << endl;
accept(ast); accept(ast);
closeAndPrintFilePath(file);
} }
protected: protected:
@@ -480,6 +492,8 @@ public:
<< endl; << endl;
accept(ast); accept(ast);
closeAndPrintFilePath(file);
} }
protected: protected:
@@ -627,7 +641,7 @@ public:
accept(ast); accept(ast);
file.close(); closeAndPrintFilePath(file);
} }
protected: protected:
@@ -761,7 +775,7 @@ public:
d.accept(unit->ast()); d.accept(unit->ast());
file.close(); closeAndPrintFilePath(file);
} }
protected: protected:
@@ -1220,6 +1234,7 @@ void generateAST_cpp(const Snapshot &snapshot, const QDir &cplusplusDir)
if (file.open(QFile::WriteOnly)) { if (file.open(QFile::WriteOnly)) {
QTextStream out(&file); QTextStream out(&file);
out << cpp_document.toPlainText(); out << cpp_document.toPlainText();
closeAndPrintFilePath(file);
} }
} }
@@ -1312,6 +1327,8 @@ void generateASTVisitor_H(const Snapshot &, const QDir &cplusplusDir,
"} // namespace CPlusPlus\n" "} // namespace CPlusPlus\n"
"\n" "\n"
"#endif // CPLUSPLUS_ASTVISITOR_H\n"; "#endif // CPLUSPLUS_ASTVISITOR_H\n";
closeAndPrintFilePath(file);
} }
void generateASTMatcher_H(const Snapshot &, const QDir &cplusplusDir, void generateASTMatcher_H(const Snapshot &, const QDir &cplusplusDir,
@@ -1353,6 +1370,8 @@ void generateASTMatcher_H(const Snapshot &, const QDir &cplusplusDir,
"} // namespace CPlusPlus\n" "} // namespace CPlusPlus\n"
"\n" "\n"
"#endif // CPLUSPLUS_ASTMATCHER_H\n"; "#endif // CPLUSPLUS_ASTMATCHER_H\n";
closeAndPrintFilePath(file);
} }
QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir, const QString &dumpersFile) QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir, const QString &dumpersFile)
@@ -1437,6 +1456,7 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir, co
if (file.open(QFile::WriteOnly)) { if (file.open(QFile::WriteOnly)) {
QTextStream out(&file); QTextStream out(&file);
out << document.toPlainText(); out << document.toPlainText();
closeAndPrintFilePath(file);
} }
Accept0CG cg(cplusplusDir, AST_h_document->translationUnit()); Accept0CG cg(cplusplusDir, AST_h_document->translationUnit());
@@ -1537,6 +1557,7 @@ void generateASTFwd_h(const Snapshot &snapshot, const QDir &cplusplusDir, const
if (file.open(QFile::WriteOnly)) { if (file.open(QFile::WriteOnly)) {
QTextStream out(&file); QTextStream out(&file);
out << document.toPlainText(); out << document.toPlainText();
closeAndPrintFilePath(file);
} }
} }
@@ -1664,36 +1685,67 @@ void generateASTPatternBuilder_h(const QDir &cplusplusDir)
<< "} // end of namespace CPlusPlus" << endl << "} // end of namespace CPlusPlus" << endl
<< endl << endl
<< "#endif // CPLUSPLUS_AST_PATTERN_BUILDER_H" << endl; << "#endif // CPLUSPLUS_AST_PATTERN_BUILDER_H" << endl;
closeAndPrintFilePath(file);
}
void printUsage()
{
const QByteArray executable = QFileInfo(qApp->arguments().first()).fileName().toLatin1();
std::cout << "Usage: " << executable.constData() << "\n"
<< " " << executable.constData() << " <frontend-dir> <dumpers-file>"
<< "\n\n"
<< "Generate appropriate header and source files of the C++ frontend accordingly\n"
<< "to AST.h and print the paths of the written files. Run this tool after\n"
<< "modifying AST.h."
<< "\n\n";
const QString defaultPathCppFrontend = QFileInfo(PATH_CPP_FRONTEND).canonicalFilePath();
const QString defaultPathDumpersFile = QFileInfo(PATH_DUMPERS_FILE).canonicalFilePath();
std::cout << "Default values:" << "\n"
<< " frontend-dir: " << qPrintable(defaultPathCppFrontend) << "\n"
<< " dumpers-file: " << qPrintable(defaultPathDumpersFile) << "\n";
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
MyQApplication app(argc, argv); MyQApplication app(argc, argv);
QStringList args = app.arguments();
args.removeFirst();
QStringList files = app.arguments(); QString pathCppFrontend = PATH_CPP_FRONTEND;
files.removeFirst(); QString pathDumpersFile = PATH_DUMPERS_FILE;
if (files.size() != 1 && files.size() != 2) { const bool helpRequested = args.contains("-h") || args.contains("-help");
std::cerr << "Usage: cplusplus [path to C++ front-end]" << std::endl; if (args.count() == 1 || args.count() >= 3 || helpRequested) {
std::cerr << " or: cplusplus [path to C++ front-end] [dumpers file name]" << std::endl; printUsage();
return EXIT_FAILURE; return helpRequested ? EXIT_SUCCESS : EXIT_FAILURE;
} else if (args.count() == 2) {
pathCppFrontend = args.at(0);
pathDumpersFile = args.at(1);
} }
QDir cplusplusDir(files.first()); QDir cplusplusDir(pathCppFrontend);
if (!QFile::exists(pathCppFrontend)) {
std::cerr << "Error: Directory \"" << qPrintable(cplusplusDir.absolutePath())
<< "\" does not exist." << std::endl;
return EXIT_FAILURE;
}
if (!QFileInfo(cplusplusDir, QLatin1String("AST.h")).exists()) { if (!QFileInfo(cplusplusDir, QLatin1String("AST.h")).exists()) {
std::cerr << "Cannot find AST.h in " << qPrintable(cplusplusDir.absolutePath()) std::cerr << "Error: Cannot find AST.h in \"" << qPrintable(cplusplusDir.absolutePath())
<< std::endl; << "\"." << std::endl;
return EXIT_FAILURE;
}
if (!QFile::exists(pathDumpersFile)) {
std::cerr << "Error: File \"" << qPrintable(pathDumpersFile)
<< "\" does not exist." << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
QString dumpersFile;
if (files.size() == 2)
dumpersFile = files.last();
Snapshot snapshot; Snapshot snapshot;
QStringList astDerivedClasses = generateAST_H(snapshot, cplusplusDir, dumpersFile); QStringList astDerivedClasses = generateAST_H(snapshot, cplusplusDir, pathDumpersFile);
astDerivedClasses.sort(); astDerivedClasses.sort();
generateASTFwd_h(snapshot, cplusplusDir, astDerivedClasses); generateASTFwd_h(snapshot, cplusplusDir, astDerivedClasses);
generateASTPatternBuilder_h(cplusplusDir); generateASTPatternBuilder_h(cplusplusDir);
return EXIT_SUCCESS;
} }

View File

@@ -0,0 +1,15 @@
QT = core gui
macx:CONFIG -= app_bundle
win32:CONFIG += console
TEMPLATE = app
TARGET = cplusplus-update-frontend
DESTDIR = ./
DEFINES += QTCREATOR_UTILS_STATIC_LIB
INCLUDEPATH += . ../../libs
include(../../../qtcreator.pri)
include(../../libs/cplusplus/cplusplus-lib.pri)
DEFINES += PATH_CPP_FRONTEND=\\\"$$PWD/../../libs/3rdparty/cplusplus\\\"
DEFINES += PATH_DUMPERS_FILE=\\\"$$PWD/../../../tests/tools/cplusplus-ast2png/dumpers.inc\\\"
SOURCES += cplusplus-update-frontend.cpp ../../libs/utils/changeset.cpp

View File

@@ -1,10 +0,0 @@
QT = core gui
macx:CONFIG -= app_bundle
TEMPLATE = app
TARGET = generate-ast
INCLUDEPATH += . ../../libs
include(../../libs/cplusplus/cplusplus-lib.pri)
# Input
SOURCES += generate-ast.cpp ../../libs/utils/changeset.cpp

View File

@@ -1,15 +0,0 @@
#define __extension__
#define __context__
#define __range__
#define __asm(a...)
#define __asm__(a...)
#define restrict
#define __restrict
#define __restrict__
// #define __weak
#define __builtin_va_arg(a,b) ((b)0)
#define __stdcall
#define __fastcall
#define __imag__
#define __real__
#define __complex__

View File

@@ -1,5 +0,0 @@
#!/bin/sh
me=$(dirname $0)
${CPP-gcc} -DCPLUSPLUS_WITHOUT_QT -U__BLOCKS__ -xc++ -E -include $me/conf.c++ ../../libs/3rdparty/cplusplus/AST.h > $me/file.i
$me/cplusplus0 $me/file.i
rm -f $me/file.i

View File

@@ -1,20 +0,0 @@
QT = core gui
macx:CONFIG -= app_bundle
TARGET = cplusplus0
INCLUDEPATH += . ../../libs
include(../../libs/cplusplus/cplusplus-lib.pri)
# Input
SOURCES += main.cpp
unix {
debug:OBJECTS_DIR = $${OUT_PWD}/.obj/debug-shared
release:OBJECTS_DIR = $${OUT_PWD}/.obj/release-shared
debug:MOC_DIR = $${OUT_PWD}/.moc/debug-shared
release:MOC_DIR = $${OUT_PWD}/.moc/release-shared
RCC_DIR = $${OUT_PWD}/.rcc/
UI_DIR = $${OUT_PWD}/.uic/
}

View File

@@ -349,6 +349,10 @@ QVariantMap AddKitOperation::addKit(const QVariantMap &map,
nameList << GetOperation::get(map, nameKey).toString(); nameList << GetOperation::get(map, nameKey).toString();
const QString uniqueName = makeUnique(displayName, nameList); const QString uniqueName = makeUnique(displayName, nameList);
QString qtId = qt;
if (!qtId.startsWith(QLatin1String("SDK.")))
qtId = QString::fromLatin1("SDK.") + qt;
// insert data: // insert data:
KeyValuePairList data; KeyValuePairList data;
data << KeyValuePair(QStringList() << kit << QLatin1String(ID), QVariant(id)); data << KeyValuePair(QStringList() << kit << QLatin1String(ID), QVariant(id));
@@ -363,7 +367,7 @@ QVariantMap AddKitOperation::addKit(const QVariantMap &map,
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << DEVICE_TYPE, QVariant(deviceType)); data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << DEVICE_TYPE, QVariant(deviceType));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << SYSROOT, QVariant(sysRoot)); data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << SYSROOT, QVariant(sysRoot));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << TOOLCHAIN, QVariant(tc)); data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << TOOLCHAIN, QVariant(tc));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << QT, QVariant(qt)); data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << QT, QVariant(qtId));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << MKSPEC, QVariant(mkspec)); data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << MKSPEC, QVariant(mkspec));
data << KeyValuePair(QStringList() << QLatin1String(DEFAULT), QVariant(defaultKit)); data << KeyValuePair(QStringList() << QLatin1String(DEFAULT), QVariant(defaultKit));

View File

@@ -37,6 +37,8 @@
#include "settings.h" #include "settings.h"
#include <QDir>
#include <iostream> #include <iostream>
// Qt version file stuff: // Qt version file stuff:
@@ -172,9 +174,15 @@ bool AddQtOperation::test() const
|| map.value(QLatin1String(VERSION)).toInt() != 1) || map.value(QLatin1String(VERSION)).toInt() != 1)
return false; return false;
#if defined Q_OS_WIN
map = addQt(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("testType"), map = addQt(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("testType"),
QLatin1String("/tmp/test/qmake"), QLatin1String("/tmp//../tmp/test\\qmake"),
KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue")))); KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
#else
map = addQt(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("testType"),
QLatin1String("/tmp//../tmp/test/qmake"),
KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
#endif
if (map.count() != 2 if (map.count() != 2
|| !map.contains(QLatin1String(VERSION)) || !map.contains(QLatin1String(VERSION))
@@ -247,8 +255,12 @@ QVariantMap AddQtOperation::addQt(const QVariantMap &map,
const QString &id, const QString &displayName, const QString &type, const QString &id, const QString &displayName, const QString &type,
const QString &qmake, const KeyValuePairList &extra) const QString &qmake, const KeyValuePairList &extra)
{ {
QString sdkId = id;
if (!id.startsWith(QLatin1String("SDK.")))
sdkId = QString::fromLatin1("SDK.") + id;
// Sanity check: Make sure autodetection source is not in use already: // Sanity check: Make sure autodetection source is not in use already:
QStringList valueKeys = FindValueOperation::findValues(map, id); QStringList valueKeys = FindValueOperation::findValues(map, sdkId);
bool hasId = false; bool hasId = false;
foreach (const QString &k, valueKeys) { foreach (const QString &k, valueKeys) {
if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(AUTODETECTION_SOURCE))) { if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(AUTODETECTION_SOURCE))) {
@@ -281,13 +293,16 @@ QVariantMap AddQtOperation::addQt(const QVariantMap &map,
nameList << GetOperation::get(map, nameKey).toString(); nameList << GetOperation::get(map, nameKey).toString();
const QString uniqueName = makeUnique(displayName, nameList); const QString uniqueName = makeUnique(displayName, nameList);
// Sanitize qmake path:
QString saneQmake = QDir::cleanPath(QDir::fromNativeSeparators(qmake));
// insert data: // insert data:
KeyValuePairList data; KeyValuePairList data;
data << KeyValuePair(QStringList() << qt << QLatin1String(ID), QVariant(-1)); data << KeyValuePair(QStringList() << qt << QLatin1String(ID), QVariant(-1));
data << KeyValuePair(QStringList() << qt << QLatin1String(DISPLAYNAME), QVariant(uniqueName)); data << KeyValuePair(QStringList() << qt << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTED), QVariant(true)); data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTED), QVariant(true));
data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTION_SOURCE), QVariant(id)); data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTION_SOURCE), QVariant(sdkId));
data << KeyValuePair(QStringList() << qt << QLatin1String(QMAKE), QVariant(qmake)); data << KeyValuePair(QStringList() << qt << QLatin1String(QMAKE), QVariant(saneQmake));
data << KeyValuePair(QStringList() << qt << QLatin1String(TYPE), QVariant(type)); data << KeyValuePair(QStringList() << qt << QLatin1String(TYPE), QVariant(type));
KeyValuePairList qtExtraList; KeyValuePairList qtExtraList;

View File

@@ -87,7 +87,7 @@ int RmQtOperation::execute() const
if (result == map) if (result == map)
return -2; return -2;
return save(map, QLatin1String("qtversion")) ? 0 : -3; return save(result, QLatin1String("qtversion")) ? 0 : -3;
} }
#ifdef WITH_TESTS #ifdef WITH_TESTS
@@ -133,12 +133,17 @@ bool RmQtOperation::test() const
QVariantMap RmQtOperation::rmQt(const QVariantMap &map, const QString &id) QVariantMap RmQtOperation::rmQt(const QVariantMap &map, const QString &id)
{ {
QString sdkId = id;
if (!id.startsWith(QLatin1String("SDK.")))
sdkId = QString::fromLatin1("SDK.") + id;
QVariantList qtList; QVariantList qtList;
for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) { for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
if (!i.key().startsWith(QLatin1String(PREFIX))) if (!i.key().startsWith(QLatin1String(PREFIX)))
continue; continue;
QVariantMap qtData = i.value().toMap(); QVariantMap qtData = i.value().toMap();
if (qtData.value(QLatin1String(AUTODETECTION_SOURCE)).toString() != id) const QString dataId = qtData.value(QLatin1String(AUTODETECTION_SOURCE)).toString();
if ((dataId != id) && (dataId != sdkId))
qtList.append(qtData); qtList.append(qtData);
} }

View File

@@ -1,5 +0,0 @@
#!/bin/sh
me=$(dirname $0)
${CPP-gcc} -U__BLOCKS__ -xc++ -E -include $me/conf.c++ $* > $me/file.i
$me/cplusplus0 $me/file.i

View File

@@ -40,6 +40,8 @@
#include <CoreTypes.h> #include <CoreTypes.h>
#include <CppDocument.h> #include <CppDocument.h>
#include "cplusplus-tools-utils.h"
#include <QFile> #include <QFile>
#include <QList> #include <QList>
#include <QCoreApplication> #include <QCoreApplication>
@@ -54,18 +56,47 @@
using namespace CPlusPlus; using namespace CPlusPlus;
void printUsage()
{
std::cout << "Usage: " << qPrintable(QFileInfo(qApp->arguments().at(0)).fileName())
<< " [-v] <file1> <file2> ...\n\n"
<< "Run the parser with the given files.\n";
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QStringList args = app.arguments();
args.removeFirst();
QStringList files = app.arguments(); bool optionVerbose = false;
files.removeFirst();
// Process options & arguments
if (args.contains("-v")) {
optionVerbose = true;
args.removeOne("-v");
}
const bool helpRequested = args.contains("-h") || args.contains("-help");
if (args.isEmpty() || helpRequested) {
printUsage();
return helpRequested ? EXIT_SUCCESS : EXIT_FAILURE;
}
// Process files
const QStringList files = args;
foreach (const QString &fileName, files) { foreach (const QString &fileName, files) {
QFile file(fileName); // Run preprocessor
if (! file.open(QFile::ReadOnly)) const QString fileNamePreprocessed = fileName + QLatin1String(".preprocessed");
continue; CplusplusToolsUtils::SystemPreprocessor preprocessor(optionVerbose);
preprocessor.preprocessFile(fileName, fileNamePreprocessed);
// Run parser
QFile file(fileNamePreprocessed);
if (! file.open(QFile::ReadOnly)) {
std::cerr << "Error: Could not open file \"" << qPrintable(file.fileName()) << "\"."
<< std::endl;
return EXIT_FAILURE;
}
const QByteArray source = file.readAll(); const QByteArray source = file.readAll();
file.close(); file.close();

View File

@@ -1,21 +1,13 @@
QT = core gui QT = core gui
macx:CONFIG -= app_bundle macx:CONFIG -= app_bundle
TARGET = cplusplus0 win32:CONFIG += console
TEMPLATE = app
TARGET = cplusplus-frontend
DESTDIR = ./
include(../../../qtcreator.pri) include(../../../qtcreator.pri)
include($$IDE_SOURCE_TREE/src/libs/cplusplus/cplusplus.pri) include($$IDE_SOURCE_TREE/src/libs/cplusplus/cplusplus-lib.pri)
include($$IDE_SOURCE_TREE/src/libs/languageutils/languageutils.pri) include($$IDE_SOURCE_TREE/tests/auto/qttestrpath.pri)
include($$IDE_SOURCE_TREE/src/libs/utils/utils.pri) include(../../../src/tools/cplusplus-tools-utils/cplusplus-tools-utils.pri)
# Input SOURCES += cplusplus-frontend.cpp
SOURCES += main.cpp
unix {
debug:OBJECTS_DIR = $${OUT_PWD}/.obj/debug-shared
release:OBJECTS_DIR = $${OUT_PWD}/.obj/release-shared
debug:MOC_DIR = $${OUT_PWD}/.moc/debug-shared
release:MOC_DIR = $${OUT_PWD}/.moc/release-shared
RCC_DIR = $${OUT_PWD}/.rcc/
UI_DIR = $${OUT_PWD}/.uic/
}

View File

@@ -89,12 +89,12 @@
#if !(USE_AUTOBREAK) #if !(USE_AUTOBREAK)
#undef USE_AUTOBREAK #undef USE_AUTOBREAK
#define USE_AUTOBREAK 1 #define USE_AUTOBREAK 1
#warning Switching on USE_AUTOBREAK #pragma message ("Switching on USE_AUTOBREAK")
#endif // !USE_AUTOBREAK #endif // !USE_AUTOBREAK
#if USE_UNINITIALIZED_AUTOBREAK #if USE_UNINITIALIZED_AUTOBREAK
#undef USE_UNINITIALIZED_AUTOBREAK #undef USE_UNINITIALIZED_AUTOBREAK
#define USE_UNINITIALIZED_AUTOBREAK 0 #define USE_UNINITIALIZED_AUTOBREAK 0
#warning Switching off USE_AUTOBREAK #pragma message ("Switching off USE_UNINITIALIZED_AUTOBREAK")
#endif // USE_UNINITIALIZED_AUTOBREAK #endif // USE_UNINITIALIZED_AUTOBREAK
#endif #endif

View File

@@ -204,7 +204,7 @@ def __getTargetFromToolTip__(toolTip):
if toolTip == None or not isinstance(toolTip, (str, unicode)): if toolTip == None or not isinstance(toolTip, (str, unicode)):
test.warning("Parameter toolTip must be of type str or unicode and can't be None!") test.warning("Parameter toolTip must be of type str or unicode and can't be None!")
return None return None
pattern = re.compile(".*<b>Target:</b>(.*)<b>Deploy.*") pattern = re.compile(".*<b>Kit:</b>(.*)<b>Deploy.*")
target = pattern.match(toolTip) target = pattern.match(toolTip)
if target == None: if target == None:
test.fatal("UI seems to have changed - expected ToolTip does not match.", test.fatal("UI seems to have changed - expected ToolTip does not match.",

View File

@@ -42,7 +42,11 @@ def main():
else: else:
pos = size pos = size
if key == "<Left>": if key == "<Left>":
pos -= 1 if platform.system() == "Darwin":
# native cursor behavior on Mac is different
pos = 0
else:
pos -= 1
test.compare(editor.textCursor().selectionStart(), pos) test.compare(editor.textCursor().selectionStart(), pos)
test.compare(editor.textCursor().selectionEnd(), pos) test.compare(editor.textCursor().selectionEnd(), pos)
test.compare(editor.textCursor().position(), pos) test.compare(editor.textCursor().position(), pos)

View File

@@ -42,6 +42,9 @@
#include <SymbolVisitor.h> #include <SymbolVisitor.h>
#include <Overview.h> #include <Overview.h>
#include "cplusplus-tools-utils.h"
#include <QDir>
#include <QFile> #include <QFile>
#include <QList> #include <QList>
#include <QCoreApplication> #include <QCoreApplication>
@@ -58,6 +61,22 @@
# include <cxxabi.h> # include <cxxabi.h>
#endif #endif
// For isatty(), _isatty()
#if defined(Q_OS_WIN)
# include <io.h>
#else
# include <unistd.h>
#endif
bool tty_for_stdin()
{
#if defined(Q_OS_WIN)
return _isatty(_fileno(stdin));
#else
return isatty(fileno(stdin));
#endif
}
using namespace CPlusPlus; using namespace CPlusPlus;
class ASTDump: protected ASTVisitor class ASTDump: protected ASTVisitor
@@ -68,9 +87,6 @@ public:
void operator()(AST *ast) { void operator()(AST *ast) {
QByteArray basename = translationUnit()->fileName(); QByteArray basename = translationUnit()->fileName();
int dotIdx = basename.lastIndexOf('.');
if (dotIdx != -1)
basename.truncate(dotIdx);
basename.append(".ast.dot"); basename.append(".ast.dot");
out.open(basename.constData()); out.open(basename.constData());
@@ -89,11 +105,10 @@ public:
out << "}" << std::endl; out << "}" << std::endl;
out.close(); out.close();
std::cout << basename.constData() << std::endl;
} }
// the following file can be generated by using: // the following file can be generated by using:
// generate-ast <path to cpp stuff> <path to dumpers.inc> // cplusplus-update-frontend <frontend-dir> <dumpers-file>
#include "dumpers.inc" #include "dumpers.inc"
protected: protected:
@@ -195,9 +210,6 @@ public:
void operator()(Symbol *s) { void operator()(Symbol *s) {
QByteArray basename = translationUnit->fileName(); QByteArray basename = translationUnit->fileName();
int dotIdx = basename.lastIndexOf('.');
if (dotIdx != -1)
basename.truncate(dotIdx);
basename.append(".symbols.dot"); basename.append(".symbols.dot");
out.open(basename.constData()); out.open(basename.constData());
@@ -218,7 +230,6 @@ public:
out << "}" << std::endl; out << "}" << std::endl;
out.close(); out.close();
std::cout << basename.constData() << std::endl;
} }
protected: protected:
@@ -351,19 +362,103 @@ private:
Overview o; Overview o;
}; };
void createImageFromDot(const QString &inputFile, const QString &outputFile, bool verbose)
{
const QString command = CplusplusToolsUtils::portableExecutableName(QLatin1String("dot"));
const QStringList arguments = QStringList()
<< QLatin1String("-Tpng") << QLatin1String("-o") << outputFile << inputFile;
CplusplusToolsUtils::executeCommand(command, arguments, QString(), verbose);
}
const char PATH_STDIN_FILE[] = "_stdincontents.cpp";
QString example()
{
return
#if defined(Q_OS_WIN)
QString::fromLatin1("> echo int foo() {} | %1 && %2.ast.png")
#elif defined(Q_OS_MAC)
QString::fromLatin1("$ echo \"int foo() {}\" | ./%1 && open %2.ast.png")
#else
QString::fromLatin1("$ echo \"int foo() {}\" | ./%1 && xdg-open %2.ast.png")
#endif
.arg(QFileInfo(qApp->arguments().at(0)).fileName(), PATH_STDIN_FILE);
}
void printUsage()
{
std::cout << "Usage: " << qPrintable(QFileInfo(qApp->arguments().at(0)).fileName())
<< " [-v] <file1> <file2> ...\n\n";
std::cout << qPrintable(QString::fromLatin1(
"Visualize AST and symbol hierarchy of given C++ files by generating png image files\n"
"in the same directory as the input files. Print paths to generated image files.\n"
"\n"
"Standard input is also read. The resulting files starts with \"%1\"\n"
"and are created in the current working directory. To show the AST for simple snippets\n"
"you might want to execute:\n"
"\n"
" %2\n"
"\n"
"Prerequisites:\n"
" 1) Make sure to have 'dot' from graphviz locatable by PATH.\n"
" 2) Make sure to have an up to date dumpers file by using 'cplusplus-update-frontend'.\n"
).arg(PATH_STDIN_FILE, example()));
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QStringList args = app.arguments();
args.removeFirst();
QStringList files = app.arguments(); bool optionVerbose = false;
files.removeFirst();
// Data from stdin?
if (!tty_for_stdin()) {
QFile file("_stdincontents.cpp");
if (! file.open(QFile::WriteOnly)) {
std::cerr << "Error: Cannot open file for writing\"" << qPrintable(file.fileName())
<< "\"" << std::endl;
exit(EXIT_FAILURE);
}
file.write(QTextStream(stdin).readAll().toLocal8Bit());
file.close();
args.append(file.fileName());
}
// Process options & arguments
if (args.contains("-v")) {
optionVerbose = true;
args.removeOne("-v");
}
const bool helpRequested = args.contains("-h") || args.contains("-help");
if (args.isEmpty() || helpRequested) {
printUsage();
return helpRequested ? EXIT_SUCCESS : EXIT_FAILURE;
}
// Process files
const QStringList files = args;
foreach (const QString &fileName, files) { foreach (const QString &fileName, files) {
QFile file(fileName); if (! QFile::exists(fileName)) {
std::cerr << "Error: File \"" << qPrintable(fileName) << "\" does not exist."
<< std::endl;
exit(EXIT_FAILURE);
}
// Run the preprocessor
const QString fileNamePreprocessed = fileName + QLatin1String(".preprocessed");
CplusplusToolsUtils::SystemPreprocessor preprocessor(optionVerbose);
preprocessor.preprocessFile(fileName, fileNamePreprocessed);
// Convert to dot
QFile file(fileNamePreprocessed);
if (! file.open(QFile::ReadOnly)) { if (! file.open(QFile::ReadOnly)) {
std::cerr << "Cannot open \"" << qPrintable(fileName) std::cerr << "Error: Could not open file \"" << qPrintable(fileNamePreprocessed)
<< "\", skipping it." << std::endl; << "\"" << std::endl;
continue; exit(EXIT_FAILURE);
} }
const QByteArray source = file.readAll(); const QByteArray source = file.readAll();
@@ -373,7 +468,6 @@ int main(int argc, char *argv[])
doc->control()->setDiagnosticClient(0); doc->control()->setDiagnosticClient(0);
doc->setUtf8Source(source); doc->setUtf8Source(source);
doc->parse(); doc->parse();
doc->check(); doc->check();
ASTDump dump(doc->translationUnit()); ASTDump dump(doc->translationUnit());
@@ -381,6 +475,18 @@ int main(int argc, char *argv[])
SymbolDump dump2(doc->translationUnit()); SymbolDump dump2(doc->translationUnit());
dump2(doc->globalNamespace()); dump2(doc->globalNamespace());
// Create images
typedef QPair<QString, QString> Pair;
QList<Pair> inputOutputFiles;
inputOutputFiles.append(qMakePair(QString(fileName + QLatin1String(".ast.dot")),
QString(fileName + QLatin1String(".ast.png"))));
inputOutputFiles.append(qMakePair(QString(fileName + QLatin1String(".symbols.dot")),
QString(fileName + QLatin1String(".symbols.png"))));
foreach (const Pair &pair, inputOutputFiles) {
createImageFromDot(pair.first, pair.second, optionVerbose);
std::cout << qPrintable(QDir::toNativeSeparators(pair.second)) << std::endl;
}
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@@ -0,0 +1,12 @@
QT = core gui
macx:CONFIG -= app_bundle
win32:CONFIG += console
TEMPLATE = app
TARGET = cplusplus-ast2png
DESTDIR = ./
include(../../../qtcreator.pri)
include(../../../src/libs/cplusplus/cplusplus-lib.pri)
include(../../../src/tools/cplusplus-tools-utils/cplusplus-tools-utils.pri)
SOURCES += cplusplus-ast2png.cpp

View File

@@ -1,5 +0,0 @@
#!/bin/sh
me=$(dirname $0)
${CPP-gcc} -U__BLOCKS__ -xc++ -E -include $me/conf.c++ $* > $me/file.i
$me/cplusplus0 $me/file.i

View File

@@ -1,15 +0,0 @@
#define __extension__
#define __context__
#define __range__
#define __asm(a...)
#define __asm__(a...)
#define restrict
#define __restrict
#define __restrict__
// #define __weak
#define __builtin_va_arg(a,b) ((b)0)
#define __stdcall
#define __fastcall
#define __imag__
#define __real__
#define __complex__

View File

@@ -1,20 +0,0 @@
QT = core gui
macx:CONFIG -= app_bundle
TARGET = cplusplus0
include(../../../qtcreator.pri)
include(../../../src/libs/cplusplus/cplusplus.pri)
# Input
SOURCES += main.cpp
unix {
debug:OBJECTS_DIR = $${OUT_PWD}/.obj/debug-shared
release:OBJECTS_DIR = $${OUT_PWD}/.obj/release-shared
debug:MOC_DIR = $${OUT_PWD}/.moc/debug-shared
release:MOC_DIR = $${OUT_PWD}/.moc/release-shared
RCC_DIR = $${OUT_PWD}/.rcc/
UI_DIR = $${OUT_PWD}/.uic/
}

View File

@@ -1,5 +1,5 @@
TEMPLATE=subdirs TEMPLATE=subdirs
SUBDIRS= \ SUBDIRS= \
cplusplus-dump \ cplusplus-ast2png \
qml-ast2dot qml-ast2dot