static int updateVersionHelper(const QString &command) { Utils::SynchronousProcess process; Utils::SynchronousProcessResponse response = process.runBlocking(command, QStringList() << QLatin1String("--version")); if (response.result != Utils::SynchronousProcessResponse::Finished) return 0; // Astyle prints the version on stdout or stderr, depending on platform const int version = parseVersion(response.stdOut().trimmed()); if (version != 0) return version; return parseVersion(response.stdErr().trimmed()); }
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 ArtisticStyleSettings::createDocumentationFile() const { Utils::SynchronousProcess process; process.setTimeoutS(2); Utils::SynchronousProcessResponse response = process.runBlocking(command(), QStringList() << QLatin1String("-h")); if (response.result != Utils::SynchronousProcessResponse::Finished) return; QFile file(documentationFilePath()); const QFileInfo fi(file); if (!fi.exists()) fi.dir().mkpath(fi.absolutePath()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) return; bool contextWritten = false; QXmlStreamWriter stream(&file); stream.setAutoFormatting(true); stream.writeStartDocument("1.0", true); stream.writeComment("Created " + QDateTime::currentDateTime().toString(Qt::ISODate)); stream.writeStartElement(Constants::DOCUMENTATION_XMLROOT); // astyle writes its output to 'error'... const QStringList lines = response.stdErr().split(QLatin1Char('\n')); QStringList keys; QStringList docu; for (QString line : lines) { line = line.trimmed(); if ((line.startsWith("--") && !line.startsWith("---")) || line.startsWith("OR ")) { const QStringList rawKeys = line.split(" OR ", QString::SkipEmptyParts); for (QString k : rawKeys) { k = k.trimmed(); k.remove('#'); keys << k; if (k.startsWith("--")) keys << k.right(k.size() - 2); } } else { if (line.isEmpty()) { if (!keys.isEmpty()) { // Write entry stream.writeStartElement(Constants::DOCUMENTATION_XMLENTRY); stream.writeStartElement(Constants::DOCUMENTATION_XMLKEYS); for (const QString &key : keys) stream.writeTextElement(Constants::DOCUMENTATION_XMLKEY, key); stream.writeEndElement(); const QString text = "<p><span class=\"option\">" + keys.filter(QRegExp("^\\-")).join(", ") + "</span></p><p>" + (docu.join(' ').toHtmlEscaped()) + "</p>"; stream.writeTextElement(Constants::DOCUMENTATION_XMLDOC, text); stream.writeEndElement(); contextWritten = true; } keys.clear(); docu.clear(); } else if (!keys.isEmpty()) { docu << line; } } } stream.writeEndElement(); stream.writeEndDocument(); // An empty file causes error messages and a contextless file preventing this function to run // again in order to generate the documentation successfully. Thus delete the file. if (!contextWritten) { file.close(); file.remove(); } }