ClangExecutableVersion clangExecutableVersion(const QString &executable) { const ClangExecutableVersion invalidVersion; // Sanity checks const QFileInfo fileInfo(executable); const bool isExecutableFile = fileInfo.isFile() && fileInfo.isExecutable(); if (!isExecutableFile) return invalidVersion; // Get version output Utils::Environment environment = Utils::Environment::systemEnvironment(); Utils::Environment::setupEnglishOutput(&environment); Utils::SynchronousProcess runner; runner.setEnvironment(environment.toStringList()); runner.setTimeoutS(10); // We would prefer "-dumpversion", but that one returns some old version number. const QStringList arguments(QLatin1String(("--version"))); const Utils::SynchronousProcessResponse response = runner.runBlocking(executable, arguments); if (response.result != Utils::SynchronousProcessResponse::Finished) return invalidVersion; const QString output = response.stdOut(); // Parse version output const QRegularExpression re(QLatin1String("clang version (\\d+)\\.(\\d+)\\.(\\d+)")); const QRegularExpressionMatch reMatch = re.match(output); if (re.captureCount() != 3) return invalidVersion; const QString majorString = reMatch.captured(1); bool convertedSuccessfully = false; const int major = majorString.toInt(&convertedSuccessfully); if (!convertedSuccessfully) return invalidVersion; const QString minorString = reMatch.captured(2); const int minor = minorString.toInt(&convertedSuccessfully); if (!convertedSuccessfully) return invalidVersion; const QString patchString = reMatch.captured(3); const int patch = patchString.toInt(&convertedSuccessfully); if (!convertedSuccessfully) return invalidVersion; return ClangExecutableVersion(major, minor, patch); }
void TCommandLine::handleTabCompletion(bool direction) { if ((mTabCompletionCount < 0) || (mUserKeptOnTyping)) { mTabCompletionTyped = toPlainText(); if (mTabCompletionTyped.size() == 0) { return; } mUserKeptOnTyping = false; mTabCompletionCount = -1; } int amount = mpHost->mpConsole->buffer.size(); if (amount > 500) { amount = 500; } QStringList bufferList = mpHost->mpConsole->buffer.getEndLines(amount); QString buffer = bufferList.join(QChar::Space); buffer.replace(QChar(0x21af), QChar::LineFeed); buffer.replace(QChar::LineFeed, QChar::Space); QStringList wordList = buffer.split(QRegularExpression(QStringLiteral(R"(\b)"), QRegularExpression::UseUnicodePropertiesOption), QString::SkipEmptyParts); if (direction) { mTabCompletionCount++; } else { mTabCompletionCount--; } if (!wordList.empty()) { if (mTabCompletionTyped.endsWith(QChar::Space)) { return; } QString lastWord; QRegularExpression reg = QRegularExpression(QStringLiteral(R"(\b(\w+)$)"), QRegularExpression::UseUnicodePropertiesOption); QRegularExpressionMatch match = reg.match(mTabCompletionTyped); int typePosition = match.capturedStart(); if (reg.captureCount() >= 1) { lastWord = match.captured(1); } else { lastWord = QString(); } QStringList filterList = wordList.filter(QRegularExpression(QStringLiteral(R"(^%1\w+)").arg(lastWord), QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption)); if (filterList.empty()) { return; } int offset = 0; for (;;) { QString tmp = filterList.back(); filterList.removeAll(tmp); filterList.insert(offset, tmp); ++offset; if (offset >= filterList.size()) { break; } } if (!filterList.empty()) { if (mTabCompletionCount >= filterList.size()) { mTabCompletionCount = filterList.size() - 1; } if (mTabCompletionCount < 0) { mTabCompletionCount = 0; } QString proposal = filterList[mTabCompletionCount]; QString userWords = mTabCompletionTyped.left(typePosition); setPlainText(QString(userWords + proposal).trimmed()); moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); mTabCompletionOld = toPlainText(); } } }