OSDN Git Service

Merge remote branch 'origin/2.1'
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / qtversionmanager.cpp
index 6210500..7e384b8 100644 (file)
 #include <coreplugin/icore.h>
 #include <coreplugin/helpmanager.h>
 #include <extensionsystem/pluginmanager.h>
-#include <help/helpmanager.h>
 #include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
+#ifdef Q_OS_WIN
+#    include <utils/winutils.h>
+#endif
 
 #include <QtCore/QFile>
 #include <QtCore/QProcess>
 #include <QtGui/QApplication>
 #include <QtGui/QDesktopServices>
 
-#ifdef Q_OS_WIN32
-#include <windows.h>
-#endif
-
 using namespace Qt4ProjectManager;
 using namespace Qt4ProjectManager::Internal;
 
@@ -825,12 +824,12 @@ void QtVersion::updateSourcePath()
 // That is returns the directory
 // To find out whether we already have a qtversion for that directory call
 // QtVersion *QtVersionManager::qtVersionForDirectory(const QString directory);
-QString QtVersionManager::findQMakeBinaryFromMakefile(const QString &directory)
+QString QtVersionManager::findQMakeBinaryFromMakefile(const QString &makefile)
 {
     bool debugAdding = false;
-    QFile makefile(directory + "/Makefile" );
-    if (makefile.exists() && makefile.open(QFile::ReadOnly)) {
-        QTextStream ts(&makefile);
+    QFile fi(makefile);
+    if (fi.exists() && fi.open(QFile::ReadOnly)) {
+        QTextStream ts(&fi);
         QRegExp r1("QMAKE\\s*=(.*)");
         while (!ts.atEnd()) {
             QString line = ts.readLine();
@@ -876,43 +875,38 @@ void dumpQMakeAssignments(const QList<QMakeAssignment> &list)
     }
 }
 
-bool QtVersionManager::makefileIsFor(const QString &directory, const QString &proFile)
+bool QtVersionManager::makefileIsFor(const QString &makefile, const QString &proFile)
 {
     if (proFile.isEmpty())
         return true;
 
-    QString line = findQMakeLine(directory, QLatin1String("# Project:")).trimmed();
+    QString line = findQMakeLine(makefile, QLatin1String("# Project:")).trimmed();
     if (line.isEmpty())
         return false;
 
-
     line = line.mid(line.indexOf(QChar(':')) + 1);
     line = line.trimmed();
 
-    QFileInfo srcFileInfo(QDir(directory), line);
+    QFileInfo srcFileInfo(QFileInfo(makefile).absoluteDir(), line);
     QFileInfo proFileInfo(proFile);
     return srcFileInfo == proFileInfo;
 }
 
-QPair<QtVersion::QmakeBuildConfigs, QStringList> QtVersionManager::scanMakeFile(const QString &directory, QtVersion::QmakeBuildConfigs defaultBuildConfig)
+QPair<QtVersion::QmakeBuildConfigs, QString> QtVersionManager::scanMakeFile(const QString &makefile, QtVersion::QmakeBuildConfigs defaultBuildConfig)
 {
     if (debug)
         qDebug()<<"ScanMakeFile, the gory details:";
     QtVersion::QmakeBuildConfigs result = defaultBuildConfig;
-    QStringList result2;
+    QString result2;
 
-    QString line = findQMakeLine(directory, QLatin1String("# Command:"));
+    QString line = findQMakeLine(makefile, QLatin1String("# Command:"));
     if (!line.isEmpty()) {
         if (debug)
             qDebug()<<"Found line"<<line;
         line = trimLine(line);
-        QStringList parts = splitLine(line);
-        if (debug)
-            qDebug()<<"Split into"<<parts;
         QList<QMakeAssignment> assignments;
         QList<QMakeAssignment> afterAssignments;
-        QStringList additionalArguments;
-        parseParts(parts, &assignments, &afterAssignments, &additionalArguments);
+        parseArgs(line, &assignments, &afterAssignments, &result2);
 
         if (debug) {
             dumpQMakeAssignments(assignments);
@@ -928,13 +922,12 @@ QPair<QtVersion::QmakeBuildConfigs, QStringList> QtVersionManager::scanMakeFile(
         if (debug)
             dumpQMakeAssignments(assignments);
 
-        result2.append(additionalArguments);
         foreach(const QMakeAssignment &qa, assignments)
-            result2.append(qa.variable + qa.op + qa.value);
+            Utils::QtcProcess::addArg(&result2, qa.variable + qa.op + qa.value);
         if (!afterAssignments.isEmpty()) {
-            result2.append("-after");
+            Utils::QtcProcess::addArg(&result2, QLatin1String("-after"));
             foreach(const QMakeAssignment &qa, afterAssignments)
-                result2.append(qa.variable + qa.op + qa.value);
+                Utils::QtcProcess::addArg(&result2, qa.variable + qa.op + qa.value);
         }
     }
 
@@ -952,11 +945,11 @@ QPair<QtVersion::QmakeBuildConfigs, QStringList> QtVersionManager::scanMakeFile(
     return qMakePair(result, result2);
 }
 
-QString QtVersionManager::findQMakeLine(const QString &directory, const QString &key)
+QString QtVersionManager::findQMakeLine(const QString &makefile, const QString &key)
 {
-    QFile makefile(directory + QLatin1String("/Makefile" ));
-    if (makefile.exists() && makefile.open(QFile::ReadOnly)) {
-        QTextStream ts(&makefile);
+    QFile fi(makefile);
+    if (fi.exists() && fi.open(QFile::ReadOnly)) {
+        QTextStream ts(&fi);
         while (!ts.atEnd()) {
             const QString line = ts.readLine();
             if (line.startsWith(key))
@@ -975,55 +968,23 @@ QString QtVersionManager::trimLine(const QString line)
     return line.mid(firstSpace).trimmed();
 }
 
-QStringList QtVersionManager::splitLine(const QString &line)
-{
-    // Split on each " ", except on those which are escaped
-    // On Unix also remove all escaping
-    // On Windows also, but different escaping
-    bool escape = false;
-    QString currentWord;
-    QStringList results;
-    int length = line.length();
-    for (int i=0; i<length; ++i) {
-#ifdef Q_OS_WIN
-        if (line.at(i) == '"') {
-            escape = !escape;
-        } else if (escape || line.at(i) != ' ') {
-            currentWord += line.at(i);
-        } else {
-            results << currentWord;
-            currentWord.clear();;
-        }
-#else
-        if (escape) {
-            currentWord += line.at(i);
-            escape = false;
-        } else if (line.at(i) == ' ') {
-            results << currentWord;
-            currentWord.clear();
-        } else if (line.at(i) == '\\') {
-            escape = true;
-        } else {
-            currentWord += line.at(i);
-        }
-#endif
-    }
-    return results;
-}
-
-void QtVersionManager::parseParts(const QStringList &parts, QList<QMakeAssignment> *assignments, QList<QMakeAssignment> *afterAssignments, QStringList *additionalArguments)
+void QtVersionManager::parseArgs(const QString &args, QList<QMakeAssignment> *assignments, QList<QMakeAssignment> *afterAssignments, QString *additionalArguments)
 {
     QRegExp regExp("([^\\s\\+-]*)\\s*(\\+=|=|-=|~=)(.*)");
     bool after = false;
     bool ignoreNext = false;
-    foreach (const QString &part, parts) {
+    *additionalArguments = args;
+    Utils::QtcProcess::ArgIterator ait(additionalArguments);
+    while (ait.next()) {
         if (ignoreNext) {
             // Ignoring
             ignoreNext = false;
-        } else if (part == "-after") {
+            ait.deleteArg();
+        } else if (ait.value() == QLatin1String("-after")) {
             after = true;
-        } else if(part.contains('=')) {
-            if (regExp.exactMatch(part)) {
+            ait.deleteArg();
+        } else if (ait.value().contains(QLatin1Char('='))) {
+            if (regExp.exactMatch(ait.value())) {
                 QMakeAssignment qa;
                 qa.variable = regExp.cap(1);
                 qa.op = regExp.cap(2);
@@ -1035,21 +996,23 @@ void QtVersionManager::parseParts(const QStringList &parts, QList<QMakeAssignmen
             } else {
                 qDebug()<<"regexp did not match";
             }
-        } else if (part == "-o") {
+            ait.deleteArg();
+        } else if (ait.value() == QLatin1String("-o")) {
             ignoreNext = true;
-        } else {
-            additionalArguments->append(part);
-        }
-    }
+            ait.deleteArg();
 #if defined(Q_OS_WIN32)
-    additionalArguments->removeAll("-win32");
+        } else if (ait.value() == QLatin1String("-win32")) {
 #elif defined(Q_OS_MAC)
-    additionalArguments->removeAll("-macx");
+        } else if (ait.value() == QLatin1String("-macx")) {
 #elif defined(Q_OS_QNX6)
-    additionalArguments->removeAll("-qnx6");
+        } else if (ait.value() == QLatin1String("-qnx6")) {
 #else
-    additionalArguments->removeAll("-unix");
+        } else if (ait.value() == QLatin1String("-unix")) {
 #endif
+            ait.deleteArg();
+        }
+    }
+    ait.deleteArg();  // The .pro file is always the last arg
 }
 
 /// This function extracts all the CONFIG+=debug, CONFIG+=release
@@ -1311,7 +1274,7 @@ QList<QSharedPointer<ProjectExplorer::ToolChain> > QtVersion::toolChains() const
     return m_toolChains;
 }
 
-ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChain::ToolChainType type) const
+ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChainType type) const
 {
     foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tcptr, toolChains())
         if (tcptr->type() == type)
@@ -1319,9 +1282,9 @@ ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChain::Too
     return 0;
 }
 
-QList<ProjectExplorer::ToolChain::ToolChainType> QtVersion::possibleToolChainTypes() const
+QList<ProjectExplorer::ToolChainType> QtVersion::possibleToolChainTypes() const
 {
-    QList<ProjectExplorer::ToolChain::ToolChainType> types;
+    QList<ProjectExplorer::ToolChainType> types;
     foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tc, toolChains())
         types << tc->type();
     return types;
@@ -1466,15 +1429,15 @@ void QtVersion::updateToolChainAndMkspec() const
             m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
             m_toolChains << ToolChainPtr(s60mgr->createGCCEToolChain(this));
             if (S60Manager::hasRvctCompiler())
-                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5))
-                             << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6));
+                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT_ARMV5))
+                             << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT_ARMV6));
             if (!mwcDirectory().isEmpty()) {
                 m_toolChains << ToolChainPtr(s60mgr->createWINSCWToolChain(this));
                 m_targetIds.insert(QLatin1String(Constants::S60_EMULATOR_TARGET_ID));
             }
 #    else
             if (S60Manager::hasRvctCompiler())
-                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC));
+                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC));
             m_toolChains << ToolChainPtr(s60mgr->createGCCE_GnuPocToolChain(this));
             m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
 #    endif
@@ -1726,24 +1689,24 @@ QStringList QtVersion::debuggingHelperLibraryLocations() const
 
 bool QtVersion::supportsBinaryDebuggingHelper() const
 {
-    foreach (ProjectExplorer::ToolChain::ToolChainType type, possibleToolChainTypes())
+    foreach (ProjectExplorer::ToolChainType type, possibleToolChainTypes())
         switch (type) {
-        case ProjectExplorer::ToolChain::GCC:
-        case ProjectExplorer::ToolChain::LINUX_ICC:
-        case ProjectExplorer::ToolChain::MinGW:
-        case ProjectExplorer::ToolChain::MSVC:
-        case ProjectExplorer::ToolChain::WINCE:
-        case ProjectExplorer::ToolChain::GCC_MAEMO:
-        case ProjectExplorer::ToolChain::OTHER:
-        case ProjectExplorer::ToolChain::UNKNOWN:
+        case ProjectExplorer::ToolChain_GCC:
+        case ProjectExplorer::ToolChain_LINUX_ICC:
+        case ProjectExplorer::ToolChain_MinGW:
+        case ProjectExplorer::ToolChain_MSVC:
+        case ProjectExplorer::ToolChain_WINCE:
+        case ProjectExplorer::ToolChain_GCC_MAEMO:
+        case ProjectExplorer::ToolChain_OTHER:
+        case ProjectExplorer::ToolChain_UNKNOWN:
             return true;
-        case ProjectExplorer::ToolChain::WINSCW:
-        case ProjectExplorer::ToolChain::GCCE :
-        case ProjectExplorer::ToolChain::RVCT_ARMV5:
-        case ProjectExplorer::ToolChain::RVCT_ARMV6:
-        case ProjectExplorer::ToolChain::GCCE_GNUPOC:
-        case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC:
-        case ProjectExplorer::ToolChain::INVALID:
+        case ProjectExplorer::ToolChain_WINSCW:
+        case ProjectExplorer::ToolChain_GCCE :
+        case ProjectExplorer::ToolChain_RVCT_ARMV5:
+        case ProjectExplorer::ToolChain_RVCT_ARMV6:
+        case ProjectExplorer::ToolChain_GCCE_GNUPOC:
+        case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
+        case ProjectExplorer::ToolChain_INVALID:
             break;
         }
     return false;
@@ -1803,22 +1766,11 @@ QString QtVersion::examplesPath() const
 
 bool QtVersion::isQt64Bit() const
 {
-        const QString make = qmakeCommand();
-//        qDebug() << make;
-        bool isAmd64 = false;
-#ifdef Q_OS_WIN32
-#  ifdef __GNUC__   // MinGW lacking some definitions/winbase.h
-#    define SCS_64BIT_BINARY 6
-#  endif
-        DWORD binaryType = 0;
-        bool success = GetBinaryTypeW(reinterpret_cast<const TCHAR*>(make.utf16()), &binaryType) != 0;
-        if (success && binaryType == SCS_64BIT_BINARY)
-            isAmd64=true;
-//        qDebug() << "isAmd64:" << isAmd64 << binaryType;
-        return isAmd64;
+#ifdef Q_OS_WIN
+    const QString qmake = qmakeCommand();
+    return qmake.isEmpty() ? false : Utils::winIs64BitBinary(qmake);
 #else
-        Q_UNUSED(isAmd64)
-        return false;
+    return false;
 #endif
 }
 
@@ -1845,7 +1797,7 @@ bool QtVersion::buildDebuggingHelperLibrary(QFutureInterface<void> &future,
         return false;
     }
     tc->addToEnvironment(env);
-    const QString target = (tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String(""));
+    const QString target = (tc->type() == ProjectExplorer::ToolChain_GCC_MAEMO ? QLatin1String("-unix") : QLatin1String(""));
 
     // invalidate cache
     m_versionInfoUpToDate = false;