forked from qt-creator/qt-creator
Documentation mentions: "Each may be either a string or an object" and "If no strategy field is given, or if the field uses the string form rather than the object form, the behavior is the same as 'set'" Task-number: QTCREATORBUG-28693 Change-Id: Idd8cdffb94e9a943e0b133a63c628d9d8d54eb20 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
672 lines
24 KiB
C++
672 lines
24 KiB
C++
// Copyright (C) 2022 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
#include "presetsparser.h"
|
|
|
|
#include "cmakeprojectmanagertr.h"
|
|
|
|
#include <utils/algorithm.h>
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
|
|
namespace CMakeProjectManager::Internal {
|
|
|
|
bool parseVersion(const QJsonValue &jsonValue, int &version)
|
|
{
|
|
if (jsonValue.isUndefined())
|
|
return false;
|
|
|
|
const int invalidVersion = -1;
|
|
version = jsonValue.toInt(invalidVersion);
|
|
return version != invalidVersion;
|
|
}
|
|
|
|
bool parseCMakeMinimumRequired(const QJsonValue &jsonValue, QVersionNumber &versionNumber)
|
|
{
|
|
if (jsonValue.isUndefined() || !jsonValue.isObject())
|
|
return false;
|
|
|
|
QJsonObject object = jsonValue.toObject();
|
|
versionNumber = QVersionNumber(object.value("major").toInt(),
|
|
object.value("minor").toInt(),
|
|
object.value("patch").toInt());
|
|
|
|
return true;
|
|
}
|
|
|
|
std::optional<QStringList> parseInclude(const QJsonValue &jsonValue)
|
|
{
|
|
std::optional<QStringList> includes;
|
|
|
|
if (!jsonValue.isUndefined()) {
|
|
if (jsonValue.isArray()) {
|
|
includes = QStringList();
|
|
const QJsonArray includeArray = jsonValue.toArray();
|
|
for (const QJsonValue &includeValue : includeArray)
|
|
includes.value() << includeValue.toString();
|
|
}
|
|
}
|
|
|
|
return includes;
|
|
}
|
|
|
|
std::optional<PresetsDetails::Condition> parseCondition(const QJsonValue &jsonValue)
|
|
{
|
|
std::optional<PresetsDetails::Condition> condition;
|
|
|
|
if (jsonValue.isUndefined())
|
|
return condition;
|
|
|
|
condition = PresetsDetails::Condition();
|
|
|
|
if (jsonValue.isNull()) {
|
|
condition->type = "null";
|
|
return condition;
|
|
}
|
|
|
|
if (jsonValue.isBool()) {
|
|
condition->type = "const";
|
|
condition->constValue = jsonValue.toBool();
|
|
return condition;
|
|
}
|
|
|
|
if (!jsonValue.isObject())
|
|
return condition;
|
|
|
|
QJsonObject object = jsonValue.toObject();
|
|
QString type = object.value("type").toString();
|
|
if (type.isEmpty())
|
|
return condition;
|
|
|
|
if (type == "const") {
|
|
condition->type = type;
|
|
condition->constValue = object.value("value").toBool();
|
|
return condition;
|
|
}
|
|
|
|
for (const auto &equals : {QString("equals"), QString("notEquals")}) {
|
|
if (type == equals) {
|
|
condition->type = equals;
|
|
condition->lhs = object.value("lhs").toString();
|
|
condition->rhs = object.value("rhs").toString();
|
|
}
|
|
}
|
|
if (!condition->type.isEmpty())
|
|
return condition;
|
|
|
|
for (const auto &inList : {QString("inList"), QString("notInList")}) {
|
|
if (type == inList) {
|
|
condition->type = inList;
|
|
condition->string = object.value("string").toString();
|
|
if (object.value("list").isArray()) {
|
|
condition->list = QStringList();
|
|
const QJsonArray listArray = object.value("list").toArray();
|
|
for (const QJsonValue &listValue : listArray)
|
|
condition->list.value() << listValue.toString();
|
|
}
|
|
}
|
|
}
|
|
if (!condition->type.isEmpty())
|
|
return condition;
|
|
|
|
for (const auto &matches : {QString("matches"), QString("notMatches")}) {
|
|
if (type == matches) {
|
|
condition->type = matches;
|
|
condition->string = object.value("string").toString();
|
|
condition->regex = object.value("regex").toString();
|
|
}
|
|
}
|
|
if (!condition->type.isEmpty())
|
|
return condition;
|
|
|
|
for (const auto &anyOf : {QString("anyOf"), QString("allOf")}) {
|
|
if (type == anyOf) {
|
|
condition->type = anyOf;
|
|
if (object.value("conditions").isArray()) {
|
|
condition->conditions = std::vector<PresetsDetails::Condition::ConditionPtr>();
|
|
const QJsonArray conditionsArray = object.value("conditions").toArray();
|
|
for (const QJsonValue &conditionsValue : conditionsArray) {
|
|
condition->conditions.value().emplace_back(
|
|
std::make_shared<PresetsDetails::Condition>(
|
|
parseCondition(conditionsValue).value()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!condition->type.isEmpty())
|
|
return condition;
|
|
|
|
if (type == "not") {
|
|
condition->type = type;
|
|
condition->condition = std::make_shared<PresetsDetails::Condition>(
|
|
parseCondition(object.value("condition")).value());
|
|
return condition;
|
|
}
|
|
|
|
return condition;
|
|
}
|
|
|
|
bool parseConfigurePresets(const QJsonValue &jsonValue,
|
|
QList<PresetsDetails::ConfigurePreset> &configurePresets,
|
|
const Utils::FilePath &fileDir)
|
|
{
|
|
// The whole section is optional
|
|
if (jsonValue.isUndefined())
|
|
return true;
|
|
|
|
if (!jsonValue.isArray())
|
|
return false;
|
|
|
|
const QJsonArray configurePresetsArray = jsonValue.toArray();
|
|
for (const QJsonValue &presetJson : configurePresetsArray) {
|
|
if (!presetJson.isObject())
|
|
continue;
|
|
|
|
QJsonObject object = presetJson.toObject();
|
|
PresetsDetails::ConfigurePreset preset;
|
|
|
|
preset.name = object.value("name").toString();
|
|
preset.fileDir = fileDir;
|
|
preset.hidden = object.value("hidden").toBool();
|
|
|
|
QJsonValue inherits = object.value("inherits");
|
|
if (!inherits.isUndefined()) {
|
|
preset.inherits = QStringList();
|
|
if (inherits.isArray()) {
|
|
const QJsonArray inheritsArray = inherits.toArray();
|
|
for (const QJsonValue &inheritsValue : inheritsArray)
|
|
preset.inherits.value() << inheritsValue.toString();
|
|
} else {
|
|
QString inheritsValue = inherits.toString();
|
|
if (!inheritsValue.isEmpty())
|
|
preset.inherits.value() << inheritsValue;
|
|
}
|
|
}
|
|
|
|
if (object.contains("condition"))
|
|
preset.condition = parseCondition(object.value("condition"));
|
|
|
|
if (object.contains("displayName"))
|
|
preset.displayName = object.value("displayName").toString();
|
|
if (object.contains("description"))
|
|
preset.description = object.value("description").toString();
|
|
if (object.contains("generator"))
|
|
preset.generator = object.value("generator").toString();
|
|
if (object.contains("binaryDir"))
|
|
preset.binaryDir = object.value("binaryDir").toString();
|
|
if (object.contains("installDir"))
|
|
preset.installDir = object.value("installDir").toString();
|
|
if (object.contains("toolchainFile"))
|
|
preset.toolchainFile = object.value("toolchainFile").toString();
|
|
if (object.contains("cmakeExecutable"))
|
|
preset.cmakeExecutable = object.value("cmakeExecutable").toString();
|
|
|
|
const QJsonObject cacheVariablesObj = object.value("cacheVariables").toObject();
|
|
for (const QString &cacheKey : cacheVariablesObj.keys()) {
|
|
if (!preset.cacheVariables)
|
|
preset.cacheVariables = CMakeConfig();
|
|
|
|
QJsonValue cacheValue = cacheVariablesObj.value(cacheKey);
|
|
if (cacheValue.isObject()) {
|
|
QJsonObject cacheVariableObj = cacheValue.toObject();
|
|
CMakeConfigItem item;
|
|
item.key = cacheKey.toUtf8();
|
|
item.type = CMakeConfigItem::typeStringToType(
|
|
cacheVariableObj.value("type").toString().toUtf8());
|
|
item.value = cacheVariableObj.value("value").toString().toUtf8();
|
|
preset.cacheVariables.value() << item;
|
|
|
|
} else {
|
|
if (cacheValue.isBool()) {
|
|
preset.cacheVariables.value()
|
|
<< CMakeConfigItem(cacheKey.toUtf8(),
|
|
CMakeConfigItem::BOOL,
|
|
cacheValue.toBool() ? "ON" : "OFF");
|
|
} else if (CMakeConfigItem::toBool(cacheValue.toString()).has_value()) {
|
|
preset.cacheVariables.value()
|
|
<< CMakeConfigItem(cacheKey.toUtf8(),
|
|
CMakeConfigItem::BOOL,
|
|
cacheValue.toString().toUtf8());
|
|
} else {
|
|
preset.cacheVariables.value()
|
|
<< CMakeConfigItem(cacheKey.toUtf8(), cacheValue.toString().toUtf8());
|
|
}
|
|
}
|
|
}
|
|
|
|
const QJsonObject environmentObj = object.value("environment").toObject();
|
|
for (const QString &envKey : environmentObj.keys()) {
|
|
if (!preset.environment)
|
|
preset.environment = Utils::Environment();
|
|
|
|
QJsonValue envValue = environmentObj.value(envKey);
|
|
preset.environment.value().set(envKey, envValue.toString());
|
|
}
|
|
|
|
const QJsonObject warningsObj = object.value("warnings").toObject();
|
|
if (!warningsObj.isEmpty()) {
|
|
preset.warnings = PresetsDetails::Warnings();
|
|
|
|
if (warningsObj.contains("dev"))
|
|
preset.warnings->dev = warningsObj.value("dev").toBool();
|
|
if (warningsObj.contains("deprecated"))
|
|
preset.warnings->deprecated = warningsObj.value("deprecated").toBool();
|
|
if (warningsObj.contains("uninitialized"))
|
|
preset.warnings->uninitialized = warningsObj.value("uninitialized").toBool();
|
|
if (warningsObj.contains("unusedCli"))
|
|
preset.warnings->unusedCli = warningsObj.value("unusedCli").toBool();
|
|
if (warningsObj.contains("systemVars"))
|
|
preset.warnings->systemVars = warningsObj.value("systemVars").toBool();
|
|
}
|
|
|
|
const QJsonObject errorsObj = object.value("errors").toObject();
|
|
if (!errorsObj.isEmpty()) {
|
|
preset.errors = PresetsDetails::Errors();
|
|
|
|
if (errorsObj.contains("dev"))
|
|
preset.errors->dev = errorsObj.value("dev").toBool();
|
|
if (errorsObj.contains("deprecated"))
|
|
preset.errors->deprecated = errorsObj.value("deprecated").toBool();
|
|
}
|
|
|
|
const QJsonObject debugObj = object.value("debug").toObject();
|
|
if (!debugObj.isEmpty()) {
|
|
preset.debug = PresetsDetails::Debug();
|
|
|
|
if (debugObj.contains("output"))
|
|
preset.debug->output = debugObj.value("output").toBool();
|
|
if (debugObj.contains("tryCompile"))
|
|
preset.debug->tryCompile = debugObj.value("tryCompile").toBool();
|
|
if (debugObj.contains("find"))
|
|
preset.debug->find = debugObj.value("find").toBool();
|
|
}
|
|
|
|
const QJsonObject architectureObj = object.value("architecture").toObject();
|
|
if (!architectureObj.isEmpty()) {
|
|
preset.architecture = PresetsDetails::ValueStrategyPair();
|
|
|
|
if (architectureObj.contains("value"))
|
|
preset.architecture->value = architectureObj.value("value").toString();
|
|
if (architectureObj.contains("strategy")) {
|
|
const QString strategy = architectureObj.value("strategy").toString();
|
|
if (strategy == "set")
|
|
preset.architecture->strategy = PresetsDetails::ValueStrategyPair::Strategy::set;
|
|
if (strategy == "external")
|
|
preset.architecture->strategy
|
|
= PresetsDetails::ValueStrategyPair::Strategy::external;
|
|
} else {
|
|
preset.architecture->strategy = PresetsDetails::ValueStrategyPair::Strategy::set;
|
|
}
|
|
} else {
|
|
const QString value = object.value("architecture").toString();
|
|
if (!value.isEmpty()) {
|
|
preset.architecture = PresetsDetails::ValueStrategyPair();
|
|
preset.architecture->value = value;
|
|
preset.architecture->strategy = PresetsDetails::ValueStrategyPair::Strategy::set;
|
|
}
|
|
}
|
|
|
|
const QJsonObject toolsetObj = object.value("toolset").toObject();
|
|
if (!toolsetObj.isEmpty()) {
|
|
preset.toolset = PresetsDetails::ValueStrategyPair();
|
|
|
|
if (toolsetObj.contains("value"))
|
|
preset.toolset->value = toolsetObj.value("value").toString();
|
|
if (toolsetObj.contains("strategy")) {
|
|
const QString strategy = toolsetObj.value("strategy").toString();
|
|
if (strategy == "set")
|
|
preset.toolset->strategy = PresetsDetails::ValueStrategyPair::Strategy::set;
|
|
if (strategy == "external")
|
|
preset.toolset->strategy = PresetsDetails::ValueStrategyPair::Strategy::external;
|
|
} else {
|
|
preset.toolset->strategy = PresetsDetails::ValueStrategyPair::Strategy::set;
|
|
}
|
|
} else {
|
|
const QString value = object.value("toolset").toString();
|
|
if (!value.isEmpty()) {
|
|
preset.toolset = PresetsDetails::ValueStrategyPair();
|
|
preset.toolset->value = value;
|
|
preset.toolset->strategy = PresetsDetails::ValueStrategyPair::Strategy::set;
|
|
}
|
|
}
|
|
|
|
configurePresets.emplace_back(preset);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool parseBuildPresets(const QJsonValue &jsonValue,
|
|
QList<PresetsDetails::BuildPreset> &buildPresets,
|
|
const Utils::FilePath &fileDir)
|
|
{
|
|
// The whole section is optional
|
|
if (jsonValue.isUndefined())
|
|
return true;
|
|
|
|
if (!jsonValue.isArray())
|
|
return false;
|
|
|
|
const QJsonArray buildPresetsArray = jsonValue.toArray();
|
|
for (const QJsonValue &presetJson : buildPresetsArray) {
|
|
if (!presetJson.isObject())
|
|
continue;
|
|
|
|
QJsonObject object = presetJson.toObject();
|
|
PresetsDetails::BuildPreset preset;
|
|
|
|
preset.name = object.value("name").toString();
|
|
preset.fileDir = fileDir;
|
|
preset.hidden = object.value("hidden").toBool();
|
|
|
|
QJsonValue inherits = object.value("inherits");
|
|
if (!inherits.isUndefined()) {
|
|
preset.inherits = QStringList();
|
|
if (inherits.isArray()) {
|
|
const QJsonArray inheritsArray = inherits.toArray();
|
|
for (const QJsonValue &inheritsValue : inheritsArray)
|
|
preset.inherits.value() << inheritsValue.toString();
|
|
} else {
|
|
QString inheritsValue = inherits.toString();
|
|
if (!inheritsValue.isEmpty())
|
|
preset.inherits.value() << inheritsValue;
|
|
}
|
|
}
|
|
|
|
if (object.contains("condition"))
|
|
preset.condition = parseCondition(object.value("condition"));
|
|
|
|
if (object.contains("displayName"))
|
|
preset.displayName = object.value("displayName").toString();
|
|
if (object.contains("description"))
|
|
preset.description = object.value("description").toString();
|
|
|
|
const QJsonObject environmentObj = object.value("environment").toObject();
|
|
for (const QString &envKey : environmentObj.keys()) {
|
|
if (!preset.environment)
|
|
preset.environment = Utils::Environment();
|
|
|
|
QJsonValue envValue = environmentObj.value(envKey);
|
|
preset.environment.value().set(envKey, envValue.toString());
|
|
}
|
|
|
|
if (object.contains("configurePreset"))
|
|
preset.configurePreset = object.value("configurePreset").toString();
|
|
if (object.contains("inheritConfigureEnvironment"))
|
|
preset.inheritConfigureEnvironment = object.value("inheritConfigureEnvironment").toBool();
|
|
if (object.contains("jobs"))
|
|
preset.jobs = object.value("jobs").toInt();
|
|
|
|
QJsonValue targets = object.value("targets");
|
|
if (!targets.isUndefined()) {
|
|
preset.targets = QStringList();
|
|
if (targets.isArray()) {
|
|
const QJsonArray targetsArray = targets.toArray();
|
|
for (const QJsonValue &targetsValue : targetsArray)
|
|
preset.targets.value() << targetsValue.toString();
|
|
} else {
|
|
QString targetsValue = targets.toString();
|
|
if (!targetsValue.isEmpty())
|
|
preset.targets.value() << targetsValue;
|
|
}
|
|
}
|
|
if (object.contains("configuration"))
|
|
preset.configuration = object.value("configuration").toString();
|
|
if (object.contains("verbose"))
|
|
preset.verbose = object.value("verbose").toBool();
|
|
if (object.contains("cleanFirst"))
|
|
preset.cleanFirst = object.value("cleanFirst").toBool();
|
|
|
|
QJsonValue nativeToolOptions = object.value("nativeToolOptions");
|
|
if (!nativeToolOptions.isUndefined()) {
|
|
if (nativeToolOptions.isArray()) {
|
|
preset.nativeToolOptions = QStringList();
|
|
const QJsonArray toolOptionsArray = nativeToolOptions.toArray();
|
|
for (const QJsonValue &toolOptionsValue : toolOptionsArray)
|
|
preset.nativeToolOptions.value() << toolOptionsValue.toString();
|
|
}
|
|
}
|
|
|
|
buildPresets.emplace_back(preset);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const PresetsData &PresetsParser::presetsData() const
|
|
{
|
|
return m_presetsData;
|
|
}
|
|
|
|
bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage, int &errorLine)
|
|
{
|
|
const Utils::expected_str<QByteArray> jsonContents = jsonFile.fileContents();
|
|
if (!jsonContents) {
|
|
errorMessage = Tr::tr("Failed to read file \"%1\".").arg(jsonFile.fileName());
|
|
return false;
|
|
}
|
|
|
|
QJsonParseError error;
|
|
const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonContents.value(), &error);
|
|
if (jsonDoc.isNull()) {
|
|
errorLine = 1;
|
|
for (int i = 0; i < error.offset; ++i)
|
|
if (jsonContents.value().at(i) == '\n')
|
|
++errorLine;
|
|
errorMessage = error.errorString();
|
|
return false;
|
|
}
|
|
|
|
if (!jsonDoc.isObject()) {
|
|
errorMessage = Tr::tr("Invalid file \"%1\".").arg(jsonFile.fileName());
|
|
return false;
|
|
}
|
|
|
|
QJsonObject root = jsonDoc.object();
|
|
|
|
m_presetsData.fileDir = jsonFile.parentDir();
|
|
|
|
if (!parseVersion(root.value("version"), m_presetsData.version)) {
|
|
errorMessage = Tr::tr("Invalid \"version\" in file \"%1\".").arg(jsonFile.fileName());
|
|
return false;
|
|
}
|
|
|
|
// optional
|
|
parseCMakeMinimumRequired(root.value("cmakeMinimumRequired"),
|
|
m_presetsData.cmakeMinimimRequired);
|
|
|
|
// optional
|
|
m_presetsData.include = parseInclude(root.value("include"));
|
|
|
|
// optional
|
|
if (!parseConfigurePresets(root.value("configurePresets"),
|
|
m_presetsData.configurePresets,
|
|
jsonFile.parentDir())) {
|
|
errorMessage
|
|
= Tr::tr("Invalid \"configurePresets\" section in %1 file").arg(jsonFile.fileName());
|
|
return false;
|
|
}
|
|
|
|
// optional
|
|
if (!parseBuildPresets(root.value("buildPresets"),
|
|
m_presetsData.buildPresets,
|
|
jsonFile.parentDir())) {
|
|
errorMessage
|
|
= Tr::tr("Invalid \"buildPresets\" section in %1 file").arg(jsonFile.fileName());
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static QHash<QString, QString> merge(const QHash<QString, QString> &first,
|
|
const QHash<QString, QString> &second)
|
|
{
|
|
QHash<QString, QString> result = first;
|
|
for (auto it = second.constKeyValueBegin(); it != second.constKeyValueEnd(); ++it) {
|
|
result[it->first] = it->second;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static CMakeConfig merge(const CMakeConfig &first, const CMakeConfig &second)
|
|
{
|
|
return Utils::setUnionMerge<CMakeConfig>(
|
|
first,
|
|
second,
|
|
[](const auto & /*left*/, const auto &right) { return right; },
|
|
&CMakeConfigItem::less);
|
|
}
|
|
|
|
static QStringList merge(const QStringList &first, const QStringList &second)
|
|
{
|
|
return Utils::setUnionMerge<QStringList>(
|
|
first,
|
|
second,
|
|
[](const auto & /*left*/, const auto &right) { return right; });
|
|
}
|
|
|
|
void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other)
|
|
{
|
|
if (!condition && other.condition && !other.condition.value().isNull())
|
|
condition = other.condition;
|
|
|
|
if (!vendor && other.vendor)
|
|
vendor = other.vendor;
|
|
|
|
if (vendor && other.vendor)
|
|
vendor = merge(other.vendor.value(), vendor.value());
|
|
|
|
if (!generator && other.generator)
|
|
generator = other.generator;
|
|
|
|
if (!architecture && other.architecture)
|
|
architecture = other.architecture;
|
|
|
|
if (!toolset && other.toolset)
|
|
toolset = other.toolset;
|
|
|
|
if (!toolchainFile && other.toolchainFile)
|
|
toolchainFile = other.toolchainFile;
|
|
|
|
if (!binaryDir && other.binaryDir)
|
|
binaryDir = other.binaryDir;
|
|
|
|
if (!installDir && other.installDir)
|
|
installDir = other.installDir;
|
|
|
|
if (!cmakeExecutable && other.cmakeExecutable)
|
|
cmakeExecutable = other.cmakeExecutable;
|
|
|
|
if (!cacheVariables && other.cacheVariables)
|
|
cacheVariables = other.cacheVariables;
|
|
else if (cacheVariables && other.cacheVariables)
|
|
cacheVariables = merge(other.cacheVariables.value(), cacheVariables.value());
|
|
|
|
if (!environment && other.environment)
|
|
environment = other.environment;
|
|
else if (environment && other.environment)
|
|
environment = environment.value().appliedToEnvironment(other.environment.value());
|
|
|
|
if (!warnings && other.warnings)
|
|
warnings = other.warnings;
|
|
|
|
if (!errors && other.errors)
|
|
errors = other.errors;
|
|
|
|
if (!debug && other.debug)
|
|
debug = other.debug;
|
|
}
|
|
|
|
void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other)
|
|
{
|
|
if (!condition && other.condition && !other.condition.value().isNull())
|
|
condition = other.condition;
|
|
|
|
if (!vendor && other.vendor)
|
|
vendor = other.vendor;
|
|
|
|
if (vendor && other.vendor)
|
|
vendor = merge(other.vendor.value(), vendor.value());
|
|
|
|
if (!environment && other.environment)
|
|
environment = other.environment;
|
|
else if (environment && other.environment)
|
|
environment = environment.value().appliedToEnvironment(other.environment.value());
|
|
|
|
if (!configurePreset && other.configurePreset)
|
|
configurePreset = other.configurePreset;
|
|
|
|
if (!inheritConfigureEnvironment && other.inheritConfigureEnvironment)
|
|
inheritConfigureEnvironment = other.inheritConfigureEnvironment;
|
|
|
|
if (!jobs && other.jobs)
|
|
jobs = other.jobs;
|
|
|
|
if (!targets && other.targets)
|
|
targets = other.targets;
|
|
else if (targets && other.targets)
|
|
targets = merge(other.targets.value(), targets.value());
|
|
|
|
if (!configuration && other.configuration)
|
|
configuration = other.configuration;
|
|
|
|
if (!verbose && other.verbose)
|
|
verbose = other.verbose;
|
|
|
|
if (!cleanFirst && other.cleanFirst)
|
|
cleanFirst = other.cleanFirst;
|
|
|
|
if (!nativeToolOptions && other.nativeToolOptions)
|
|
nativeToolOptions = other.nativeToolOptions;
|
|
else if (nativeToolOptions && other.nativeToolOptions)
|
|
nativeToolOptions = merge(other.nativeToolOptions.value(), nativeToolOptions.value());
|
|
}
|
|
|
|
bool PresetsDetails::Condition::evaluate() const
|
|
{
|
|
if (isNull())
|
|
return true;
|
|
|
|
if (isConst() && constValue)
|
|
return constValue.value();
|
|
|
|
if (isEquals() && lhs && rhs)
|
|
return lhs.value() == rhs.value();
|
|
|
|
if (isNotEquals() && lhs && rhs)
|
|
return lhs.value() != rhs.value();
|
|
|
|
if (isInList() && string && list)
|
|
return list.value().contains(string.value());
|
|
|
|
if (isNotInList() && string && list)
|
|
return !list.value().contains(string.value());
|
|
|
|
if (isMatches() && string && regex) {
|
|
QRegularExpression qRegex(regex.value());
|
|
return qRegex.match(string.value()).hasMatch();
|
|
}
|
|
|
|
if (isNotMatches() && string && regex) {
|
|
QRegularExpression qRegex(regex.value());
|
|
return !qRegex.match(string.value()).hasMatch();
|
|
}
|
|
|
|
if (isAnyOf() && conditions)
|
|
return Utils::anyOf(conditions.value(), [](const ConditionPtr &c) { return c->evaluate(); });
|
|
|
|
if (isAllOf() && conditions)
|
|
return Utils::allOf(conditions.value(), [](const ConditionPtr &c) { return c->evaluate(); });
|
|
|
|
if (isNot() && condition)
|
|
return !condition.value()->evaluate();
|
|
|
|
return false;
|
|
}
|
|
|
|
} // CMakeProjectManager::Internal
|