diff options
Diffstat (limited to 'Source')
24 files changed, 1733 insertions, 1355 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index a9aec6c..b31b8dc 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -161,10 +161,13 @@ set(SRCS cmCLocaleEnvironmentScope.cxx cmCMakePath.h cmCMakePath.cxx - cmCMakePresetsFile.cxx - cmCMakePresetsFile.h - cmCMakePresetsFileInternal.h - cmCMakePresetsFileReadJSON.cxx + cmCMakePresetsGraph.cxx + cmCMakePresetsGraph.h + cmCMakePresetsGraphInternal.h + cmCMakePresetsGraphReadJSON.cxx + cmCMakePresetsGraphReadJSONBuildPresets.cxx + cmCMakePresetsGraphReadJSONConfigurePresets.cxx + cmCMakePresetsGraphReadJSONTestPresets.cxx cmCommandArgumentParserHelper.cxx cmCommonTargetGenerator.cxx cmCommonTargetGenerator.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 3812150..94bbea1 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 22) -set(CMake_VERSION_PATCH 20220110) +set(CMake_VERSION_PATCH 20220112) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 1785571..f90b781 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -730,12 +730,12 @@ void CMakeSetupDialog::updatePreset(const QString& name) } void CMakeSetupDialog::showPresetLoadError( - const QString& dir, cmCMakePresetsFile::ReadFileResult result) + const QString& dir, cmCMakePresetsGraph::ReadFileResult result) { QMessageBox::warning( this, "Error Reading CMake Presets", QString::fromLocal8Bit("Could not read presets from %1: %2") - .arg(dir, cmCMakePresetsFile::ResultToString(result))); + .arg(dir, cmCMakePresetsGraph::ResultToString(result))); } void CMakeSetupDialog::doBinaryBrowse() diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index f0cc929..8aee70d 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -60,7 +60,7 @@ protected slots: void updatePresets(const QVector<QCMakePreset>& presets); void updatePreset(const QString& name); void showPresetLoadError(const QString& dir, - cmCMakePresetsFile::ReadFileResult result); + cmCMakePresetsGraph::ReadFileResult result); void showProgress(const QString& msg, float percent); void setEnabledState(bool); bool setupFirstConfigure(); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 8ab8656..ffb6157 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -32,7 +32,7 @@ QCMake::QCMake(QObject* p) qRegisterMetaType<QCMakePropertyList>(); qRegisterMetaType<QProcessEnvironment>(); qRegisterMetaType<QVector<QCMakePreset>>(); - qRegisterMetaType<cmCMakePresetsFile::ReadFileResult>(); + qRegisterMetaType<cmCMakePresetsGraph::ReadFileResult>(); cmSystemTools::DisableRunCommandOutput(); cmSystemTools::SetRunCommandHideConsole(true); @@ -69,9 +69,9 @@ QCMake::QCMake(QObject* p) connect(&this->LoadPresetsTimer, &QTimer::timeout, this, [this]() { this->loadPresets(); if (!this->PresetName.isEmpty() && - this->CMakePresetsFile.ConfigurePresets.find( + this->CMakePresetsGraph.ConfigurePresets.find( std::string(this->PresetName.toLocal8Bit())) == - this->CMakePresetsFile.ConfigurePresets.end()) { + this->CMakePresetsGraph.ConfigurePresets.end()) { this->setPreset(QString{}); } }); @@ -159,7 +159,7 @@ void QCMake::setPreset(const QString& name, bool setBinary) if (!name.isNull()) { std::string presetName(name.toLocal8Bit()); auto const& expandedPreset = - this->CMakePresetsFile.ConfigurePresets[presetName].Expanded; + this->CMakePresetsGraph.ConfigurePresets[presetName].Expanded; if (expandedPreset) { if (setBinary && !expandedPreset->BinaryDir.empty()) { QString binaryDir = @@ -427,7 +427,7 @@ QCMakePropertyList QCMake::properties() const if (!this->PresetName.isNull()) { std::string presetName(this->PresetName.toLocal8Bit()); auto const& p = - this->CMakePresetsFile.ConfigurePresets.at(presetName).Expanded; + this->CMakePresetsGraph.ConfigurePresets.at(presetName).Expanded; if (p) { for (auto const& v : p->CacheVariables) { if (!v.second) { @@ -533,17 +533,17 @@ void QCMake::setUpEnvironment() const void QCMake::loadPresets() { - auto result = this->CMakePresetsFile.ReadProjectPresets( + auto result = this->CMakePresetsGraph.ReadProjectPresets( this->SourceDirectory.toLocal8Bit().data(), true); if (result != this->LastLoadPresetsResult && - result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { emit this->presetLoadError(this->SourceDirectory, result); } this->LastLoadPresetsResult = result; QVector<QCMakePreset> presets; - for (auto const& name : this->CMakePresetsFile.ConfigurePresetOrder) { - auto const& it = this->CMakePresetsFile.ConfigurePresets[name]; + for (auto const& name : this->CMakePresetsGraph.ConfigurePresetOrder) { + auto const& it = this->CMakePresetsGraph.ConfigurePresets[name]; auto const& p = it.Unexpanded; if (p.Hidden) { continue; @@ -556,10 +556,10 @@ void QCMake::loadPresets() preset.generator = QString::fromLocal8Bit(p.Generator.data()); preset.architecture = QString::fromLocal8Bit(p.Architecture.data()); preset.setArchitecture = !p.ArchitectureStrategy || - p.ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; + p.ArchitectureStrategy == cmCMakePresetsGraph::ArchToolsetStrategy::Set; preset.toolset = QString::fromLocal8Bit(p.Toolset.data()); preset.setToolset = !p.ToolsetStrategy || - p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; + p.ToolsetStrategy == cmCMakePresetsGraph::ArchToolsetStrategy::Set; preset.enabled = it.Expanded && it.Expanded->ConditionResult && std::find_if(this->AvailableGenerators.begin(), this->AvailableGenerators.end(), diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index a6751b0..8a7e4cb 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -4,7 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include "cmake.h" #ifdef _MSC_VER @@ -60,7 +60,7 @@ using QCMakePropertyList = QList<QCMakeProperty>; Q_DECLARE_METATYPE(QCMakeProperty) Q_DECLARE_METATYPE(QCMakePropertyList) Q_DECLARE_METATYPE(QProcessEnvironment) -Q_DECLARE_METATYPE(cmCMakePresetsFile::ReadFileResult) +Q_DECLARE_METATYPE(cmCMakePresetsGraph::ReadFileResult) /// Qt API for CMake library. /// Wrapper like class allows for easier integration with @@ -159,7 +159,7 @@ signals: void presetChanged(const QString& name); /// signal when there's an error reading the presets files void presetLoadError(const QString& dir, - cmCMakePresetsFile::ReadFileResult error); + cmCMakePresetsGraph::ReadFileResult error); /// signal when uninitialized warning changes void warnUninitializedModeChanged(bool value); /// signal for progress events @@ -202,9 +202,9 @@ protected: QString Platform; QString Toolset; std::vector<cmake::GeneratorInfo> AvailableGenerators; - cmCMakePresetsFile CMakePresetsFile; - cmCMakePresetsFile::ReadFileResult LastLoadPresetsResult = - cmCMakePresetsFile::ReadFileResult::READ_OK; + cmCMakePresetsGraph CMakePresetsGraph; + cmCMakePresetsGraph::ReadFileResult LastLoadPresetsResult = + cmCMakePresetsGraph::ReadFileResult::READ_OK; QString PresetName; QString CMakeExecutable; QAtomicInt InterruptFlag; diff --git a/Source/QtDialog/QCMakePreset.h b/Source/QtDialog/QCMakePreset.h index 1609fcb..7387655 100644 --- a/Source/QtDialog/QCMakePreset.h +++ b/Source/QtDialog/QCMakePreset.h @@ -5,7 +5,7 @@ #include <QString> #include <QVariant> -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" class QCMakePreset { diff --git a/Source/cmCMakePresetsFileInternal.h b/Source/cmCMakePresetsFileInternal.h deleted file mode 100644 index afb00ce..0000000 --- a/Source/cmCMakePresetsFileInternal.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include <memory> - -#include "cmCMakePresetsFile.h" - -#define CHECK_OK(expr) \ - do { \ - auto _result = expr; \ - if (_result != ReadFileResult::READ_OK) \ - return _result; \ - } while (false) - -namespace cmCMakePresetsFileInternal { -enum class ExpandMacroResult -{ - Ok, - Ignore, - Error, -}; - -using MacroExpander = std::function<ExpandMacroResult( - const std::string&, const std::string&, std::string&, int version)>; -} - -class cmCMakePresetsFile::Condition -{ -public: - virtual ~Condition() = default; - - virtual bool Evaluate( - const std::vector<cmCMakePresetsFileInternal::MacroExpander>& expanders, - int version, cm::optional<bool>& out) const = 0; - virtual bool IsNull() const { return false; } -}; - -namespace cmCMakePresetsFileInternal { - -class NullCondition : public cmCMakePresetsFile::Condition -{ - bool Evaluate(const std::vector<MacroExpander>& /*expanders*/, - int /*version*/, cm::optional<bool>& out) const override - { - out = true; - return true; - } - - bool IsNull() const override { return true; } -}; - -class ConstCondition : public cmCMakePresetsFile::Condition -{ -public: - bool Evaluate(const std::vector<MacroExpander>& /*expanders*/, - int /*version*/, cm::optional<bool>& out) const override - { - out = this->Value; - return true; - } - - bool Value; -}; - -class EqualsCondition : public cmCMakePresetsFile::Condition -{ -public: - bool Evaluate(const std::vector<MacroExpander>& expanders, int version, - cm::optional<bool>& out) const override; - - std::string Lhs; - std::string Rhs; -}; - -class InListCondition : public cmCMakePresetsFile::Condition -{ -public: - bool Evaluate(const std::vector<MacroExpander>& expanders, int version, - cm::optional<bool>& out) const override; - - std::string String; - std::vector<std::string> List; -}; - -class MatchesCondition : public cmCMakePresetsFile::Condition -{ -public: - bool Evaluate(const std::vector<MacroExpander>& expanders, int version, - cm::optional<bool>& out) const override; - - std::string String; - std::string Regex; -}; - -class AnyAllOfCondition : public cmCMakePresetsFile::Condition -{ -public: - bool Evaluate(const std::vector<MacroExpander>& expanders, int version, - cm::optional<bool>& out) const override; - - std::vector<std::unique_ptr<Condition>> Conditions; - bool StopValue; -}; - -class NotCondition : public cmCMakePresetsFile::Condition -{ -public: - bool Evaluate(const std::vector<MacroExpander>& expanders, int version, - cm::optional<bool>& out) const override; - - std::unique_ptr<Condition> SubCondition; -}; -} diff --git a/Source/cmCMakePresetsFileReadJSON.cxx b/Source/cmCMakePresetsFileReadJSON.cxx deleted file mode 100644 index 489551d..0000000 --- a/Source/cmCMakePresetsFileReadJSON.cxx +++ /dev/null @@ -1,1032 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include <functional> -#include <map> -#include <string> -#include <utility> -#include <vector> - -#include <cm/memory> -#include <cm/optional> -#include <cmext/string_view> - -#include <cm3p/json/reader.h> -#include <cm3p/json/value.h> - -#include "cmsys/FStream.hxx" - -#include "cmCMakePresetsFile.h" -#include "cmCMakePresetsFileInternal.h" -#include "cmJSONHelpers.h" -#include "cmVersion.h" - -namespace { -using ReadFileResult = cmCMakePresetsFile::ReadFileResult; -using CacheVariable = cmCMakePresetsFile::CacheVariable; -using ConfigurePreset = cmCMakePresetsFile::ConfigurePreset; -using BuildPreset = cmCMakePresetsFile::BuildPreset; -using TestPreset = cmCMakePresetsFile::TestPreset; -using ArchToolsetStrategy = cmCMakePresetsFile::ArchToolsetStrategy; - -constexpr int MIN_VERSION = 1; -constexpr int MAX_VERSION = 3; - -struct CMakeVersion -{ - unsigned int Major = 0; - unsigned int Minor = 0; - unsigned int Patch = 0; -}; - -struct RootPresets -{ - CMakeVersion CMakeMinimumRequired; - std::vector<cmCMakePresetsFile::ConfigurePreset> ConfigurePresets; - std::vector<cmCMakePresetsFile::BuildPreset> BuildPresets; - std::vector<cmCMakePresetsFile::TestPreset> TestPresets; -}; - -std::unique_ptr<cmCMakePresetsFileInternal::NotCondition> InvertCondition( - std::unique_ptr<cmCMakePresetsFile::Condition> condition) -{ - auto retval = cm::make_unique<cmCMakePresetsFileInternal::NotCondition>(); - retval->SubCondition = std::move(condition); - return retval; -} - -auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); - -auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); - -auto const ConditionStringListHelper = - cmJSONVectorHelper<std::string, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, - ConditionStringHelper); - -auto const ConstConditionHelper = - cmJSONObjectHelper<cmCMakePresetsFileInternal::ConstCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) - .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) - .Bind("value"_s, &cmCMakePresetsFileInternal::ConstCondition::Value, - ConditionBoolHelper, true); - -auto const EqualsConditionHelper = - cmJSONObjectHelper<cmCMakePresetsFileInternal::EqualsCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) - .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) - .Bind("lhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Lhs, - ConditionStringHelper, true) - .Bind("rhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Rhs, - ConditionStringHelper, true); - -auto const InListConditionHelper = - cmJSONObjectHelper<cmCMakePresetsFileInternal::InListCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) - .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) - .Bind("string"_s, &cmCMakePresetsFileInternal::InListCondition::String, - ConditionStringHelper, true) - .Bind("list"_s, &cmCMakePresetsFileInternal::InListCondition::List, - ConditionStringListHelper, true); - -auto const MatchesConditionHelper = - cmJSONObjectHelper<cmCMakePresetsFileInternal::MatchesCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) - .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) - .Bind("string"_s, &cmCMakePresetsFileInternal::MatchesCondition::String, - ConditionStringHelper, true) - .Bind("regex"_s, &cmCMakePresetsFileInternal::MatchesCondition::Regex, - ConditionStringHelper, true); - -ReadFileResult SubConditionHelper( - std::unique_ptr<cmCMakePresetsFile::Condition>& out, - const Json::Value* value); - -auto const ListConditionVectorHelper = - cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsFile::Condition>, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, - SubConditionHelper); -auto const AnyAllOfConditionHelper = - cmJSONObjectHelper<cmCMakePresetsFileInternal::AnyAllOfCondition, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_CONDITION, false) - .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) - .Bind("conditions"_s, - &cmCMakePresetsFileInternal::AnyAllOfCondition::Conditions, - ListConditionVectorHelper); - -auto const NotConditionHelper = - cmJSONObjectHelper<cmCMakePresetsFileInternal::NotCondition, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) - .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) - .Bind("condition"_s, - &cmCMakePresetsFileInternal::NotCondition::SubCondition, - SubConditionHelper); - -ReadFileResult ConditionHelper( - std::unique_ptr<cmCMakePresetsFile::Condition>& out, - const Json::Value* value) -{ - if (!value) { - out.reset(); - return ReadFileResult::READ_OK; - } - - if (value->isBool()) { - auto c = cm::make_unique<cmCMakePresetsFileInternal::ConstCondition>(); - c->Value = value->asBool(); - out = std::move(c); - return ReadFileResult::READ_OK; - } - - if (value->isNull()) { - out = cm::make_unique<cmCMakePresetsFileInternal::NullCondition>(); - return ReadFileResult::READ_OK; - } - - if (value->isObject()) { - if (!value->isMember("type")) { - return ReadFileResult::INVALID_CONDITION; - } - - if (!(*value)["type"].isString()) { - return ReadFileResult::INVALID_CONDITION; - } - auto type = (*value)["type"].asString(); - - if (type == "const") { - auto c = cm::make_unique<cmCMakePresetsFileInternal::ConstCondition>(); - CHECK_OK(ConstConditionHelper(*c, value)); - out = std::move(c); - return ReadFileResult::READ_OK; - } - - if (type == "equals" || type == "notEquals") { - auto c = cm::make_unique<cmCMakePresetsFileInternal::EqualsCondition>(); - CHECK_OK(EqualsConditionHelper(*c, value)); - out = std::move(c); - if (type == "notEquals") { - out = InvertCondition(std::move(out)); - } - return ReadFileResult::READ_OK; - } - - if (type == "inList" || type == "notInList") { - auto c = cm::make_unique<cmCMakePresetsFileInternal::InListCondition>(); - CHECK_OK(InListConditionHelper(*c, value)); - out = std::move(c); - if (type == "notInList") { - out = InvertCondition(std::move(out)); - } - return ReadFileResult::READ_OK; - } - - if (type == "matches" || type == "notMatches") { - auto c = cm::make_unique<cmCMakePresetsFileInternal::MatchesCondition>(); - CHECK_OK(MatchesConditionHelper(*c, value)); - out = std::move(c); - if (type == "notMatches") { - out = InvertCondition(std::move(out)); - } - return ReadFileResult::READ_OK; - } - - if (type == "anyOf" || type == "allOf") { - auto c = - cm::make_unique<cmCMakePresetsFileInternal::AnyAllOfCondition>(); - c->StopValue = (type == "anyOf"); - CHECK_OK(AnyAllOfConditionHelper(*c, value)); - out = std::move(c); - return ReadFileResult::READ_OK; - } - - if (type == "not") { - auto c = cm::make_unique<cmCMakePresetsFileInternal::NotCondition>(); - CHECK_OK(NotConditionHelper(*c, value)); - out = std::move(c); - return ReadFileResult::READ_OK; - } - } - - return ReadFileResult::INVALID_CONDITION; -} - -ReadFileResult PresetConditionHelper( - std::shared_ptr<cmCMakePresetsFile::Condition>& out, - const Json::Value* value) -{ - std::unique_ptr<cmCMakePresetsFile::Condition> ptr; - auto result = ConditionHelper(ptr, value); - out = std::move(ptr); - return result; -} - -ReadFileResult SubConditionHelper( - std::unique_ptr<cmCMakePresetsFile::Condition>& out, - const Json::Value* value) -{ - std::unique_ptr<cmCMakePresetsFile::Condition> ptr; - auto result = ConditionHelper(ptr, value); - if (ptr && ptr->IsNull()) { - return ReadFileResult::INVALID_CONDITION; - } - out = std::move(ptr); - return result; -} - -cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error) -{ - return [error](std::nullptr_t& /*out*/, - const Json::Value* value) -> ReadFileResult { - if (!value) { - return ReadFileResult::READ_OK; - } - - if (!value->isObject()) { - return error; - } - - return ReadFileResult::READ_OK; - }; -} - -auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); - -auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>( - ReadFileResult::NO_VERSION, VersionIntHelper); - -auto const RootVersionHelper = - cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_ROOT) - .Bind("version"_s, VersionHelper, false); - -auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); - -ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) -{ - if (!value) { - out.clear(); - return ReadFileResult::READ_OK; - } - - if (value->isBool()) { - out = value->asBool() ? "TRUE" : "FALSE"; - return ReadFileResult::READ_OK; - } - - return VariableStringHelper(out, value); -} - -auto const VariableObjectHelper = - cmJSONObjectHelper<CacheVariable, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) - .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) - .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); - -ReadFileResult VariableHelper(cm::optional<CacheVariable>& out, - const Json::Value* value) -{ - if (value->isBool()) { - out = CacheVariable{ - /*Type=*/"BOOL", - /*Value=*/value->asBool() ? "TRUE" : "FALSE", - }; - return ReadFileResult::READ_OK; - } - if (value->isString()) { - out = CacheVariable{ - /*Type=*/"", - /*Value=*/value->asString(), - }; - return ReadFileResult::READ_OK; - } - if (value->isObject()) { - out.emplace(); - return VariableObjectHelper(*out, value); - } - if (value->isNull()) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - return ReadFileResult::INVALID_VARIABLE; -} - -auto const VariablesHelper = - cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); - -auto const PresetStringHelper = cmJSONStringHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -ReadFileResult EnvironmentHelper(cm::optional<std::string>& out, - const Json::Value* value) -{ - if (!value || value->isNull()) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - if (value->isString()) { - out = value->asString(); - return ReadFileResult::READ_OK; - } - return ReadFileResult::INVALID_PRESET; -} - -auto const EnvironmentMapHelper = - cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, - EnvironmentHelper); - -auto const PresetVectorStringHelper = - cmJSONVectorHelper<std::string, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, - PresetStringHelper); - -ReadFileResult PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out, - const Json::Value* value) -{ - out.clear(); - if (!value) { - return ReadFileResult::READ_OK; - } - - if (value->isString()) { - out.push_back(value->asString()); - return ReadFileResult::READ_OK; - } - - return PresetVectorStringHelper(out, value); -} - -auto const PresetBoolHelper = cmJSONBoolHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -auto const PresetOptionalBoolHelper = - cmJSONOptionalHelper<bool, ReadFileResult>(ReadFileResult::READ_OK, - PresetBoolHelper); - -auto const PresetIntHelper = cmJSONIntHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -auto const PresetOptionalIntHelper = cmJSONOptionalHelper<int, ReadFileResult>( - ReadFileResult::READ_OK, PresetIntHelper); - -auto const PresetVectorIntHelper = cmJSONVectorHelper<int, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper); - -auto const PresetWarningsHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("dev"_s, &ConfigurePreset::WarnDev, PresetOptionalBoolHelper, false) - .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated, - PresetOptionalBoolHelper, false) - .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized, - PresetOptionalBoolHelper, false) - .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli, - PresetOptionalBoolHelper, false) - .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars, - PresetOptionalBoolHelper, false); - -auto const PresetErrorsHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("dev"_s, &ConfigurePreset::ErrorDev, PresetOptionalBoolHelper, false) - .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, - PresetOptionalBoolHelper, false); - -auto const PresetDebugHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("output"_s, &ConfigurePreset::DebugOutput, PresetOptionalBoolHelper, - false) - .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile, - PresetOptionalBoolHelper, false) - .Bind("find"_s, &ConfigurePreset::DebugFind, PresetOptionalBoolHelper, - false); - -ReadFileResult ArchToolsetStrategyHelper( - cm::optional<ArchToolsetStrategy>& out, const Json::Value* value) -{ - if (!value) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "set") { - out = ArchToolsetStrategy::Set; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "external") { - out = ArchToolsetStrategy::External; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -std::function<ReadFileResult(ConfigurePreset&, const Json::Value*)> -ArchToolsetHelper( - std::string ConfigurePreset::*valueField, - cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField) -{ - auto const objectHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("value", valueField, PresetStringHelper, false) - .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); - return [valueField, strategyField, objectHelper]( - ConfigurePreset& out, const Json::Value* value) -> ReadFileResult { - if (!value) { - (out.*valueField).clear(); - out.*strategyField = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isString()) { - out.*valueField = value->asString(); - out.*strategyField = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isObject()) { - return objectHelper(out, value); - } - - return ReadFileResult::INVALID_PRESET; - }; -} - -auto const ArchitectureHelper = ArchToolsetHelper( - &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); -auto const ToolsetHelper = ArchToolsetHelper( - &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); - -auto const ConfigurePresetHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &ConfigurePreset::Name, PresetStringHelper) - .Bind("inherits"_s, &ConfigurePreset::Inherits, - PresetVectorOneOrMoreStringHelper, false) - .Bind("hidden"_s, &ConfigurePreset::Hidden, PresetBoolHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &ConfigurePreset::DisplayName, PresetStringHelper, - false) - .Bind("description"_s, &ConfigurePreset::Description, PresetStringHelper, - false) - .Bind("generator"_s, &ConfigurePreset::Generator, PresetStringHelper, - false) - .Bind("architecture"_s, ArchitectureHelper, false) - .Bind("toolset"_s, ToolsetHelper, false) - .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile, - PresetStringHelper, false) - .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, PresetStringHelper, - false) - .Bind("installDir"_s, &ConfigurePreset::InstallDir, PresetStringHelper, - false) - .Bind<std::string>("cmakeExecutable"_s, nullptr, PresetStringHelper, false) - .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables, - VariablesHelper, false) - .Bind("environment"_s, &ConfigurePreset::Environment, EnvironmentMapHelper, - false) - .Bind("warnings"_s, PresetWarningsHelper, false) - .Bind("errors"_s, PresetErrorsHelper, false) - .Bind("debug"_s, PresetDebugHelper, false) - .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, - PresetConditionHelper, false); - -auto const BuildPresetHelper = - cmJSONObjectHelper<BuildPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &BuildPreset::Name, PresetStringHelper) - .Bind("inherits"_s, &BuildPreset::Inherits, - PresetVectorOneOrMoreStringHelper, false) - .Bind("hidden"_s, &BuildPreset::Hidden, PresetBoolHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &BuildPreset::DisplayName, PresetStringHelper, - false) - .Bind("description"_s, &BuildPreset::Description, PresetStringHelper, - false) - .Bind("environment"_s, &BuildPreset::Environment, EnvironmentMapHelper, - false) - .Bind("configurePreset"_s, &BuildPreset::ConfigurePreset, - PresetStringHelper, false) - .Bind("inheritConfigureEnvironment"_s, - &BuildPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, - false) - .Bind("jobs"_s, &BuildPreset::Jobs, PresetOptionalIntHelper, false) - .Bind("targets"_s, &BuildPreset::Targets, - PresetVectorOneOrMoreStringHelper, false) - .Bind("configuration"_s, &BuildPreset::Configuration, PresetStringHelper, - false) - .Bind("cleanFirst"_s, &BuildPreset::CleanFirst, PresetOptionalBoolHelper, - false) - .Bind("verbose"_s, &BuildPreset::Verbose, PresetOptionalBoolHelper, false) - .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, - PresetVectorStringHelper, false) - .Bind("condition"_s, &BuildPreset::ConditionEvaluator, - PresetConditionHelper, false); - -ReadFileResult TestPresetOutputVerbosityHelper( - TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) -{ - if (!value) { - out = TestPreset::OutputOptions::VerbosityEnum::Default; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "default") { - out = TestPreset::OutputOptions::VerbosityEnum::Default; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "verbose") { - out = TestPreset::OutputOptions::VerbosityEnum::Verbose; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "extra") { - out = TestPreset::OutputOptions::VerbosityEnum::Extra; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalOutputVerbosityHelper = - cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetOutputVerbosityHelper); - -auto const TestPresetOptionalOutputHelper = - cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress, - PresetOptionalBoolHelper, false) - .Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity, - TestPresetOptionalOutputVerbosityHelper, false) - .Bind("debug"_s, &TestPreset::OutputOptions::Debug, - PresetOptionalBoolHelper, false) - .Bind("outputOnFailure"_s, &TestPreset::OutputOptions::OutputOnFailure, - PresetOptionalBoolHelper, false) - .Bind("quiet"_s, &TestPreset::OutputOptions::Quiet, - PresetOptionalBoolHelper, false) - .Bind("outputLogFile"_s, &TestPreset::OutputOptions::OutputLogFile, - PresetStringHelper, false) - .Bind("labelSummary"_s, &TestPreset::OutputOptions::LabelSummary, - PresetOptionalBoolHelper, false) - .Bind("subprojectSummary"_s, - &TestPreset::OutputOptions::SubprojectSummary, - PresetOptionalBoolHelper, false) - .Bind("maxPassedTestOutputSize"_s, - &TestPreset::OutputOptions::MaxPassedTestOutputSize, - PresetOptionalIntHelper, false) - .Bind("maxFailedTestOutputSize"_s, - &TestPreset::OutputOptions::MaxFailedTestOutputSize, - PresetOptionalIntHelper, false) - .Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth, - PresetOptionalIntHelper, false)); - -auto const TestPresetOptionalFilterIncludeIndexObjectHelper = - cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions, - ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start, - PresetOptionalIntHelper, false) - .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End, - PresetOptionalIntHelper, false) - .Bind("stride"_s, &TestPreset::IncludeOptions::IndexOptions::Stride, - PresetOptionalIntHelper, false) - .Bind("specificTests"_s, - &TestPreset::IncludeOptions::IndexOptions::SpecificTests, - PresetVectorIntHelper, false)); - -ReadFileResult TestPresetOptionalFilterIncludeIndexHelper( - cm::optional<TestPreset::IncludeOptions::IndexOptions>& out, - const Json::Value* value) -{ - if (!value) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isString()) { - out.emplace(); - out->IndexFile = value->asString(); - return ReadFileResult::READ_OK; - } - - if (value->isObject()) { - return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value); - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalFilterIncludeHelper = - cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("name"_s, &TestPreset::IncludeOptions::Name, PresetStringHelper, - false) - .Bind("label"_s, &TestPreset::IncludeOptions::Label, PresetStringHelper, - false) - .Bind("index"_s, &TestPreset::IncludeOptions::Index, - TestPresetOptionalFilterIncludeIndexHelper, false) - .Bind("useUnion"_s, &TestPreset::IncludeOptions::UseUnion, - PresetOptionalBoolHelper, false)); - -auto const TestPresetOptionalFilterExcludeFixturesHelper = - cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions, - ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any, - PresetStringHelper, false) - .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup, - PresetStringHelper, false) - .Bind("cleanup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Cleanup, - PresetStringHelper, false)); - -auto const TestPresetOptionalFilterExcludeHelper = - cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("name"_s, &TestPreset::ExcludeOptions::Name, PresetStringHelper, - false) - .Bind("label"_s, &TestPreset::ExcludeOptions::Label, PresetStringHelper, - false) - .Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures, - TestPresetOptionalFilterExcludeFixturesHelper, false)); - -ReadFileResult TestPresetExecutionShowOnlyHelper( - TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value) -{ - if (!value || !value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "human") { - out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "json-v1") { - out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionShowOnlyHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetExecutionShowOnlyHelper); - -ReadFileResult TestPresetExecutionModeHelper( - TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out, - const Json::Value* value) -{ - if (!value) { - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "until-fail") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "until-pass") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "after-timeout") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionRepeatHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions, - ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode, - TestPresetExecutionModeHelper, true) - .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count, - PresetIntHelper, true)); - -ReadFileResult TestPresetExecutionNoTestsActionHelper( - TestPreset::ExecutionOptions::NoTestsActionEnum& out, - const Json::Value* value) -{ - if (!value) { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "default") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "error") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "ignore") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionNoTestsActionHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetExecutionNoTestsActionHelper); - -auto const TestPresetExecutionHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure, - PresetOptionalBoolHelper, false) - .Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover, - PresetOptionalBoolHelper, false) - .Bind("jobs"_s, &TestPreset::ExecutionOptions::Jobs, - PresetOptionalIntHelper, false) - .Bind("resourceSpecFile"_s, - &TestPreset::ExecutionOptions::ResourceSpecFile, - PresetStringHelper, false) - .Bind("testLoad"_s, &TestPreset::ExecutionOptions::TestLoad, - PresetOptionalIntHelper, false) - .Bind("showOnly"_s, &TestPreset::ExecutionOptions::ShowOnly, - TestPresetOptionalExecutionShowOnlyHelper, false) - .Bind("repeat"_s, &TestPreset::ExecutionOptions::Repeat, - TestPresetOptionalExecutionRepeatHelper, false) - .Bind("interactiveDebugging"_s, - &TestPreset::ExecutionOptions::InteractiveDebugging, - PresetOptionalBoolHelper, false) - .Bind("scheduleRandom"_s, &TestPreset::ExecutionOptions::ScheduleRandom, - PresetOptionalBoolHelper, false) - .Bind("timeout"_s, &TestPreset::ExecutionOptions::Timeout, - PresetOptionalIntHelper, false) - .Bind("noTestsAction"_s, &TestPreset::ExecutionOptions::NoTestsAction, - TestPresetOptionalExecutionNoTestsActionHelper, false)); - -auto const TestPresetFilterHelper = - cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("include"_s, &TestPreset::FilterOptions::Include, - TestPresetOptionalFilterIncludeHelper, false) - .Bind("exclude"_s, &TestPreset::FilterOptions::Exclude, - TestPresetOptionalFilterExcludeHelper, false)); - -auto const TestPresetHelper = - cmJSONObjectHelper<TestPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &TestPreset::Name, PresetStringHelper) - .Bind("inherits"_s, &TestPreset::Inherits, - PresetVectorOneOrMoreStringHelper, false) - .Bind("hidden"_s, &TestPreset::Hidden, PresetBoolHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &TestPreset::DisplayName, PresetStringHelper, false) - .Bind("description"_s, &TestPreset::Description, PresetStringHelper, false) - .Bind("environment"_s, &TestPreset::Environment, EnvironmentMapHelper, - false) - .Bind("configurePreset"_s, &TestPreset::ConfigurePreset, - PresetStringHelper, false) - .Bind("inheritConfigureEnvironment"_s, - &TestPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, - false) - .Bind("configuration"_s, &TestPreset::Configuration, PresetStringHelper, - false) - .Bind("overwriteConfigurationFile"_s, - &TestPreset::OverwriteConfigurationFile, PresetVectorStringHelper, - false) - .Bind("output"_s, &TestPreset::Output, TestPresetOptionalOutputHelper, - false) - .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false) - .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper, - false) - .Bind("condition"_s, &TestPreset::ConditionEvaluator, - PresetConditionHelper, false); - -auto const ConfigurePresetsHelper = - cmJSONVectorHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, - ConfigurePresetHelper); - -auto const BuildPresetsHelper = - cmJSONVectorHelper<BuildPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, - BuildPresetHelper); - -auto const TestPresetsHelper = cmJSONVectorHelper<TestPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, TestPresetHelper); - -auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); - -auto const CMakeVersionHelper = - cmJSONObjectHelper<CMakeVersion, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) - .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) - .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) - .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); - -auto const RootPresetsHelper = - cmJSONObjectHelper<RootPresets, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) - .Bind<int>("version"_s, nullptr, VersionHelper) - .Bind("configurePresets"_s, &RootPresets::ConfigurePresets, - ConfigurePresetsHelper, false) - .Bind("buildPresets"_s, &RootPresets::BuildPresets, BuildPresetsHelper, - false) - .Bind("testPresets"_s, &RootPresets::TestPresets, TestPresetsHelper, false) - .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, - CMakeVersionHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_ROOT), false); -} - -cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( - const std::string& filename, bool user) -{ - cmsys::ifstream fin(filename.c_str()); - if (!fin) { - return ReadFileResult::FILE_NOT_FOUND; - } - // If there's a BOM, toss it. - cmsys::FStream::ReadBOM(fin); - - Json::Value root; - Json::CharReaderBuilder builder; - Json::CharReaderBuilder::strictMode(&builder.settings_); - if (!Json::parseFromStream(builder, fin, &root, nullptr)) { - return ReadFileResult::JSON_PARSE_ERROR; - } - - int v = 0; - auto result = RootVersionHelper(v, &root); - if (result != ReadFileResult::READ_OK) { - return result; - } - if (v < MIN_VERSION || v > MAX_VERSION) { - return ReadFileResult::UNRECOGNIZED_VERSION; - } - if (user) { - this->UserVersion = v; - } else { - this->Version = v; - } - - // Support for build and test presets added in version 2. - if (v < 2 && - (root.isMember("buildPresets") || root.isMember("testPresets"))) { - return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED; - } - - RootPresets presets; - if ((result = RootPresetsHelper(presets, &root)) != - ReadFileResult::READ_OK) { - return result; - } - - unsigned int currentMajor = cmVersion::GetMajorVersion(); - unsigned int currentMinor = cmVersion::GetMinorVersion(); - unsigned int currentPatch = cmVersion::GetPatchVersion(); - auto const& required = presets.CMakeMinimumRequired; - if (required.Major > currentMajor || - (required.Major == currentMajor && - (required.Minor > currentMinor || - (required.Minor == currentMinor && - (required.Patch > currentPatch))))) { - return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION; - } - - for (auto& preset : presets.ConfigurePresets) { - preset.User = user; - if (preset.Name.empty()) { - return ReadFileResult::INVALID_PRESET; - } - - PresetPair<ConfigurePreset> presetPair; - presetPair.Unexpanded = preset; - presetPair.Expanded = cm::nullopt; - if (!this->ConfigurePresets - .emplace(std::make_pair(preset.Name, presetPair)) - .second) { - return ReadFileResult::DUPLICATE_PRESETS; - } - - // Support for installDir presets added in version 3. - if (v < 3 && !preset.InstallDir.empty()) { - return ReadFileResult::INSTALL_PREFIX_UNSUPPORTED; - } - - // Support for conditions added in version 3. - if (v < 3 && preset.ConditionEvaluator) { - return ReadFileResult::CONDITION_UNSUPPORTED; - } - - // Support for toolchainFile presets added in version 3. - if (v < 3 && !preset.ToolchainFile.empty()) { - return ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED; - } - - this->ConfigurePresetOrder.push_back(preset.Name); - } - - for (auto& preset : presets.BuildPresets) { - preset.User = user; - if (preset.Name.empty()) { - return ReadFileResult::INVALID_PRESET; - } - - PresetPair<BuildPreset> presetPair; - presetPair.Unexpanded = preset; - presetPair.Expanded = cm::nullopt; - if (!this->BuildPresets.emplace(preset.Name, presetPair).second) { - return ReadFileResult::DUPLICATE_PRESETS; - } - - // Support for conditions added in version 3. - if (v < 3 && preset.ConditionEvaluator) { - return ReadFileResult::CONDITION_UNSUPPORTED; - } - - this->BuildPresetOrder.push_back(preset.Name); - } - - for (auto& preset : presets.TestPresets) { - preset.User = user; - if (preset.Name.empty()) { - return ReadFileResult::INVALID_PRESET; - } - - PresetPair<TestPreset> presetPair; - presetPair.Unexpanded = preset; - presetPair.Expanded = cm::nullopt; - if (!this->TestPresets.emplace(preset.Name, presetPair).second) { - return ReadFileResult::DUPLICATE_PRESETS; - } - - // Support for conditions added in version 3. - if (v < 3 && preset.ConditionEvaluator) { - return ReadFileResult::CONDITION_UNSUPPORTED; - } - - this->TestPresetOrder.push_back(preset.Name); - } - - return ReadFileResult::READ_OK; -} diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsGraph.cxx index 4a0742a..58dca36 100644 --- a/Source/cmCMakePresetsFile.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -1,8 +1,9 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include <algorithm> +#include <cassert> #include <cstdlib> #include <functional> #include <iostream> @@ -13,7 +14,7 @@ #include "cmsys/RegularExpression.hxx" -#include "cmCMakePresetsFileInternal.h" +#include "cmCMakePresetsGraphInternal.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -38,12 +39,12 @@ enum class CycleStatus Verified, }; -using ReadFileResult = cmCMakePresetsFile::ReadFileResult; -using ConfigurePreset = cmCMakePresetsFile::ConfigurePreset; -using BuildPreset = cmCMakePresetsFile::BuildPreset; -using TestPreset = cmCMakePresetsFile::TestPreset; -using ExpandMacroResult = cmCMakePresetsFileInternal::ExpandMacroResult; -using MacroExpander = cmCMakePresetsFileInternal::MacroExpander; +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; +using BuildPreset = cmCMakePresetsGraph::BuildPreset; +using TestPreset = cmCMakePresetsGraph::TestPreset; +using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult; +using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander; void InheritString(std::string& child, const std::string& parent) { @@ -77,9 +78,10 @@ void InheritVector(std::vector<T>& child, const std::vector<T>& parent) */ template <class T> ReadFileResult VisitPreset( - T& preset, std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets, + T& preset, + std::map<std::string, cmCMakePresetsGraph::PresetPair<T>>& presets, std::map<std::string, CycleStatus> cycleStatus, - const cmCMakePresetsFile& file) + const cmCMakePresetsGraph& graph) { switch (cycleStatus[preset.Name]) { case CycleStatus::InProgress: @@ -105,11 +107,11 @@ ReadFileResult VisitPreset( } auto& parentPreset = parent->second.Unexpanded; - if (!preset.User && parentPreset.User) { - return ReadFileResult::USER_PRESET_INHERITANCE; + if (!preset.OriginFile->ReachableFiles.count(parentPreset.OriginFile)) { + return ReadFileResult::PRESET_UNREACHABLE_FROM_FILE; } - auto result = VisitPreset(parentPreset, presets, cycleStatus, file); + auto result = VisitPreset(parentPreset, presets, cycleStatus, graph); if (result != ReadFileResult::READ_OK) { return result; } @@ -129,7 +131,7 @@ ReadFileResult VisitPreset( preset.ConditionEvaluator.reset(); } - CHECK_OK(preset.VisitPresetAfterInherit(file.GetVersion(preset))); + CHECK_OK(preset.VisitPresetAfterInherit(graph.GetVersion(preset))); cycleStatus[preset.Name] = CycleStatus::Verified; return ReadFileResult::READ_OK; @@ -137,8 +139,8 @@ ReadFileResult VisitPreset( template <class T> ReadFileResult ComputePresetInheritance( - std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets, - const cmCMakePresetsFile& file) + std::map<std::string, cmCMakePresetsGraph::PresetPair<T>>& presets, + const cmCMakePresetsGraph& graph) { std::map<std::string, CycleStatus> cycleStatus; for (auto const& it : presets) { @@ -147,7 +149,7 @@ ReadFileResult ComputePresetInheritance( for (auto& it : presets) { auto& preset = it.second.Unexpanded; - auto result = VisitPreset<T>(preset, presets, cycleStatus, file); + auto result = VisitPreset<T>(preset, presets, cycleStatus, graph); if (result != ReadFileResult::READ_OK) { return result; } @@ -189,17 +191,17 @@ ExpandMacroResult ExpandMacro(std::string& out, const std::vector<MacroExpander>& macroExpanders, int version); -bool ExpandMacros(const cmCMakePresetsFile& file, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const ConfigurePreset& preset, cm::optional<ConfigurePreset>& out, const std::vector<MacroExpander>& macroExpanders) { std::string binaryDir = preset.BinaryDir; - CHECK_EXPAND(out, binaryDir, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, binaryDir, macroExpanders, graph.GetVersion(preset)); if (!binaryDir.empty()) { if (!cmSystemTools::FileIsFullPath(binaryDir)) { - binaryDir = cmStrCat(file.SourceDir, '/', binaryDir); + binaryDir = cmStrCat(graph.SourceDir, '/', binaryDir); } out->BinaryDir = cmSystemTools::CollapseFullPath(binaryDir); cmSystemTools::ConvertToUnixSlashes(out->BinaryDir); @@ -207,10 +209,10 @@ bool ExpandMacros(const cmCMakePresetsFile& file, if (!preset.InstallDir.empty()) { std::string installDir = preset.InstallDir; - CHECK_EXPAND(out, installDir, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, installDir, macroExpanders, graph.GetVersion(preset)); if (!cmSystemTools::FileIsFullPath(installDir)) { - installDir = cmStrCat(file.SourceDir, '/', installDir); + installDir = cmStrCat(graph.SourceDir, '/', installDir); } out->InstallDir = cmSystemTools::CollapseFullPath(installDir); cmSystemTools::ConvertToUnixSlashes(out->InstallDir); @@ -218,89 +220,89 @@ bool ExpandMacros(const cmCMakePresetsFile& file, if (!preset.ToolchainFile.empty()) { std::string toolchain = preset.ToolchainFile; - CHECK_EXPAND(out, toolchain, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, toolchain, macroExpanders, graph.GetVersion(preset)); out->ToolchainFile = toolchain; } for (auto& variable : out->CacheVariables) { if (variable.second) { CHECK_EXPAND(out, variable.second->Value, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } } return true; } -bool ExpandMacros(const cmCMakePresetsFile& file, const BuildPreset& preset, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const BuildPreset& preset, cm::optional<BuildPreset>& out, const std::vector<MacroExpander>& macroExpanders) { for (auto& target : out->Targets) { - CHECK_EXPAND(out, target, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, target, macroExpanders, graph.GetVersion(preset)); } for (auto& nativeToolOption : out->NativeToolOptions) { CHECK_EXPAND(out, nativeToolOption, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } return true; } -bool ExpandMacros(const cmCMakePresetsFile& file, const TestPreset& preset, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const TestPreset& preset, cm::optional<TestPreset>& out, const std::vector<MacroExpander>& macroExpanders) { for (auto& overwrite : out->OverwriteConfigurationFile) { - CHECK_EXPAND(out, overwrite, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, overwrite, macroExpanders, graph.GetVersion(preset)); } if (out->Output) { CHECK_EXPAND(out, out->Output->OutputLogFile, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } if (out->Filter) { if (out->Filter->Include) { CHECK_EXPAND(out, out->Filter->Include->Name, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Include->Label, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); if (out->Filter->Include->Index) { CHECK_EXPAND(out, out->Filter->Include->Index->IndexFile, - macroExpanders, file.GetVersion(preset)); + macroExpanders, graph.GetVersion(preset)); } } if (out->Filter->Exclude) { CHECK_EXPAND(out, out->Filter->Exclude->Name, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Exclude->Label, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); if (out->Filter->Exclude->Fixtures) { CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Any, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Setup, - macroExpanders, file.GetVersion(preset)); + macroExpanders, graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Cleanup, - macroExpanders, file.GetVersion(preset)); + macroExpanders, graph.GetVersion(preset)); } } } if (out->Execution) { CHECK_EXPAND(out, out->Execution->ResourceSpecFile, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } return true; } template <class T> -bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const T& preset, cm::optional<T>& out) { out.emplace(preset); @@ -313,20 +315,20 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, std::vector<MacroExpander> macroExpanders; MacroExpander defaultMacroExpander = - [&file, &preset](const std::string& macroNamespace, - const std::string& macroName, std::string& macroOut, - int version) -> ExpandMacroResult { + [&graph, &preset](const std::string& macroNamespace, + const std::string& macroName, std::string& macroOut, + int version) -> ExpandMacroResult { if (macroNamespace.empty()) { if (macroName == "sourceDir") { - macroOut += file.SourceDir; + macroOut += graph.SourceDir; return ExpandMacroResult::Ok; } if (macroName == "sourceParentDir") { - macroOut += cmSystemTools::GetParentDirectory(file.SourceDir); + macroOut += cmSystemTools::GetParentDirectory(graph.SourceDir); return ExpandMacroResult::Ok; } if (macroName == "sourceDirName") { - macroOut += cmSystemTools::GetFilenameName(file.SourceDir); + macroOut += cmSystemTools::GetFilenameName(graph.SourceDir); return ExpandMacroResult::Ok; } if (macroName == "presetName") { @@ -336,7 +338,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, if (macroName == "generator") { // Generator only makes sense if preset is not hidden. if (!preset.Hidden) { - macroOut += file.GetGeneratorForPreset(preset.Name); + macroOut += graph.GetGeneratorForPreset(preset.Name); } return ExpandMacroResult::Ok; } @@ -393,7 +395,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, for (auto& v : out->Environment) { if (v.second) { switch (VisitEnv(*v.second, envCycles[v.first], macroExpanders, - file.GetVersion(preset))) { + graph.GetVersion(preset))) { case ExpandMacroResult::Error: return false; case ExpandMacroResult::Ignore: @@ -408,7 +410,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, if (preset.ConditionEvaluator) { cm::optional<bool> result; if (!preset.ConditionEvaluator->Evaluate( - macroExpanders, file.GetVersion(preset), result)) { + macroExpanders, graph.GetVersion(preset), result)) { return false; } if (!result) { @@ -418,7 +420,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, out->ConditionResult = *result; } - return ExpandMacros(file, preset, out, macroExpanders); + return ExpandMacros(graph, preset, out, macroExpanders); } ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, @@ -541,7 +543,7 @@ ExpandMacroResult ExpandMacro(std::string& out, } } -bool cmCMakePresetsFileInternal::EqualsCondition::Evaluate( +bool cmCMakePresetsGraphInternal::EqualsCondition::Evaluate( const std::vector<MacroExpander>& expanders, int version, cm::optional<bool>& out) const { @@ -555,7 +557,7 @@ bool cmCMakePresetsFileInternal::EqualsCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::InListCondition::Evaluate( +bool cmCMakePresetsGraphInternal::InListCondition::Evaluate( const std::vector<MacroExpander>& expanders, int version, cm::optional<bool>& out) const { @@ -574,7 +576,7 @@ bool cmCMakePresetsFileInternal::InListCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::MatchesCondition::Evaluate( +bool cmCMakePresetsGraphInternal::MatchesCondition::Evaluate( const std::vector<MacroExpander>& expanders, int version, cm::optional<bool>& out) const { @@ -592,7 +594,7 @@ bool cmCMakePresetsFileInternal::MatchesCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::AnyAllOfCondition::Evaluate( +bool cmCMakePresetsGraphInternal::AnyAllOfCondition::Evaluate( const std::vector<MacroExpander>& expanders, int version, cm::optional<bool>& out) const { @@ -618,7 +620,7 @@ bool cmCMakePresetsFileInternal::AnyAllOfCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::NotCondition::Evaluate( +bool cmCMakePresetsGraphInternal::NotCondition::Evaluate( const std::vector<MacroExpander>& expanders, int version, cm::optional<bool>& out) const { @@ -633,9 +635,9 @@ bool cmCMakePresetsFileInternal::NotCondition::Evaluate( return true; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ConfigurePreset::VisitPresetInherit( - const cmCMakePresetsFile::Preset& parentPreset) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ConfigurePreset::VisitPresetInherit( + const cmCMakePresetsGraph::Preset& parentPreset) { auto& preset = *this; const ConfigurePreset& parent = @@ -667,8 +669,8 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetInherit( return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ConfigurePreset::VisitPresetBeforeInherit() +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ConfigurePreset::VisitPresetBeforeInherit() { auto& preset = *this; if (preset.Environment.count("") != 0) { @@ -678,8 +680,8 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetBeforeInherit() return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit(int version) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ConfigurePreset::VisitPresetAfterInherit(int version) { auto& preset = *this; if (!preset.Hidden) { @@ -706,9 +708,9 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit(int version) return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::BuildPreset::VisitPresetInherit( - const cmCMakePresetsFile::Preset& parentPreset) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::BuildPreset::VisitPresetInherit( + const cmCMakePresetsGraph::Preset& parentPreset) { auto& preset = *this; const BuildPreset& parent = static_cast<const BuildPreset&>(parentPreset); @@ -726,8 +728,8 @@ cmCMakePresetsFile::BuildPreset::VisitPresetInherit( return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit(int /* version */) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::BuildPreset::VisitPresetAfterInherit(int /* version */) { auto& preset = *this; if (!preset.Hidden && preset.ConfigurePreset.empty()) { @@ -736,9 +738,9 @@ cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit(int /* version */) return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::TestPreset::VisitPresetInherit( - const cmCMakePresetsFile::Preset& parentPreset) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::TestPreset::VisitPresetInherit( + const cmCMakePresetsGraph::Preset& parentPreset) { auto& preset = *this; const TestPreset& parent = static_cast<const TestPreset&>(parentPreset); @@ -836,8 +838,8 @@ cmCMakePresetsFile::TestPreset::VisitPresetInherit( return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit(int /* version */) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::TestPreset::VisitPresetAfterInherit(int /* version */) { auto& preset = *this; if (!preset.Hidden && preset.ConfigurePreset.empty()) { @@ -846,17 +848,17 @@ cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit(int /* version */) return ReadFileResult::READ_OK; } -std::string cmCMakePresetsFile::GetFilename(const std::string& sourceDir) +std::string cmCMakePresetsGraph::GetFilename(const std::string& sourceDir) { return cmStrCat(sourceDir, "/CMakePresets.json"); } -std::string cmCMakePresetsFile::GetUserFilename(const std::string& sourceDir) +std::string cmCMakePresetsGraph::GetUserFilename(const std::string& sourceDir) { return cmStrCat(sourceDir, "/CMakeUserPresets.json"); } -cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadProjectPresets( +cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadProjectPresets( const std::string& sourceDir, bool allowNoFiles) { this->SourceDir = sourceDir; @@ -870,28 +872,33 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadProjectPresets( return result; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ReadProjectPresetsInternal(bool allowNoFiles) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles) { bool haveOneFile = false; + File* file; std::string filename = GetUserFilename(this->SourceDir); + std::vector<File*> inProgressFiles; if (cmSystemTools::FileExists(filename)) { - auto result = this->ReadJSONFile(filename, true); + auto result = this->ReadJSONFile(filename, RootType::User, + ReadReason::Root, inProgressFiles, file); if (result != ReadFileResult::READ_OK) { return result; } haveOneFile = true; - } - - filename = GetFilename(this->SourceDir); - if (cmSystemTools::FileExists(filename)) { - auto result = this->ReadJSONFile(filename, false); - if (result != ReadFileResult::READ_OK) { - return result; + } else { + filename = GetFilename(this->SourceDir); + if (cmSystemTools::FileExists(filename)) { + auto result = this->ReadJSONFile( + filename, RootType::Project, ReadReason::Root, inProgressFiles, file); + if (result != ReadFileResult::READ_OK) { + return result; + } + haveOneFile = true; } - haveOneFile = true; } + assert(inProgressFiles.empty()); if (!haveOneFile) { return allowNoFiles ? ReadFileResult::READ_OK @@ -951,7 +958,7 @@ cmCMakePresetsFile::ReadProjectPresetsInternal(bool allowNoFiles) return ReadFileResult::READ_OK; } -const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) +const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result) { switch (result) { case ReadFileResult::READ_OK: @@ -982,13 +989,17 @@ const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) return "Duplicate presets"; case ReadFileResult::CYCLIC_PRESET_INHERITANCE: return "Cyclic preset inheritance"; - case ReadFileResult::USER_PRESET_INHERITANCE: - return "Project preset inherits from user preset"; + case ReadFileResult::PRESET_UNREACHABLE_FROM_FILE: + return "Inherited preset is unreachable from preset's file"; case ReadFileResult::INVALID_MACRO_EXPANSION: return "Invalid macro expansion"; case ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED: return "File version must be 2 or higher for build and test preset " "support."; + case ReadFileResult::INCLUDE_UNSUPPORTED: + return "File version must be 4 or higher for include support"; + case ReadFileResult::INVALID_INCLUDE: + return "Invalid \"include\" field"; case ReadFileResult::INVALID_CONFIGURE_PRESET: return "Invalid \"configurePreset\" field"; case ReadFileResult::INSTALL_PREFIX_UNSUPPORTED: @@ -1001,12 +1012,16 @@ const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) case ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED: return "File version must be 3 or higher for toolchainFile preset " "support."; + case ReadFileResult::CYCLIC_INCLUDE: + return "Cyclic include among preset files"; + case ReadFileResult::INCLUDE_OUTSIDE_PROJECT: + return "File included from outside project directory"; } return "Unknown error"; } -void cmCMakePresetsFile::ClearPresets() +void cmCMakePresetsGraph::ClearPresets() { this->ConfigurePresets.clear(); this->BuildPresets.clear(); @@ -1015,10 +1030,12 @@ void cmCMakePresetsFile::ClearPresets() this->ConfigurePresetOrder.clear(); this->BuildPresetOrder.clear(); this->TestPresetOrder.clear(); + + this->Files.clear(); } -void cmCMakePresetsFile::PrintPresets( - const std::vector<const cmCMakePresetsFile::Preset*>& presets) +void cmCMakePresetsGraph::PrintPresets( + const std::vector<const cmCMakePresetsGraph::Preset*>& presets) { if (presets.empty()) { return; @@ -1026,8 +1043,8 @@ void cmCMakePresetsFile::PrintPresets( auto longestPresetName = std::max_element(presets.begin(), presets.end(), - [](const cmCMakePresetsFile::Preset* a, - const cmCMakePresetsFile::Preset* b) { + [](const cmCMakePresetsGraph::Preset* a, + const cmCMakePresetsGraph::Preset* b) { return a->Name.length() < b->Name.length(); }); auto longestLength = (*longestPresetName)->Name.length(); @@ -1045,67 +1062,67 @@ void cmCMakePresetsFile::PrintPresets( } } -void cmCMakePresetsFile::PrintConfigurePresetList() const +void cmCMakePresetsGraph::PrintConfigurePresetList() const { PrintConfigurePresetList([](const ConfigurePreset&) { return true; }); } -void cmCMakePresetsFile::PrintConfigurePresetList( +void cmCMakePresetsGraph::PrintConfigurePresetList( const std::function<bool(const ConfigurePreset&)>& filter) const { - std::vector<const cmCMakePresetsFile::Preset*> presets; + std::vector<const cmCMakePresetsGraph::Preset*> presets; for (auto const& p : this->ConfigurePresetOrder) { auto const& preset = this->ConfigurePresets.at(p); if (!preset.Unexpanded.Hidden && preset.Expanded && preset.Expanded->ConditionResult && filter(preset.Unexpanded)) { presets.push_back( - static_cast<const cmCMakePresetsFile::Preset*>(&preset.Unexpanded)); + static_cast<const cmCMakePresetsGraph::Preset*>(&preset.Unexpanded)); } } if (!presets.empty()) { std::cout << "Available configure presets:\n\n"; - cmCMakePresetsFile::PrintPresets(presets); + cmCMakePresetsGraph::PrintPresets(presets); } } -void cmCMakePresetsFile::PrintBuildPresetList() const +void cmCMakePresetsGraph::PrintBuildPresetList() const { - std::vector<const cmCMakePresetsFile::Preset*> presets; + std::vector<const cmCMakePresetsGraph::Preset*> presets; for (auto const& p : this->BuildPresetOrder) { auto const& preset = this->BuildPresets.at(p); if (!preset.Unexpanded.Hidden && preset.Expanded && preset.Expanded->ConditionResult) { presets.push_back( - static_cast<const cmCMakePresetsFile::Preset*>(&preset.Unexpanded)); + static_cast<const cmCMakePresetsGraph::Preset*>(&preset.Unexpanded)); } } if (!presets.empty()) { std::cout << "Available build presets:\n\n"; - cmCMakePresetsFile::PrintPresets(presets); + cmCMakePresetsGraph::PrintPresets(presets); } } -void cmCMakePresetsFile::PrintTestPresetList() const +void cmCMakePresetsGraph::PrintTestPresetList() const { - std::vector<const cmCMakePresetsFile::Preset*> presets; + std::vector<const cmCMakePresetsGraph::Preset*> presets; for (auto const& p : this->TestPresetOrder) { auto const& preset = this->TestPresets.at(p); if (!preset.Unexpanded.Hidden && preset.Expanded && preset.Expanded->ConditionResult) { presets.push_back( - static_cast<const cmCMakePresetsFile::Preset*>(&preset.Unexpanded)); + static_cast<const cmCMakePresetsGraph::Preset*>(&preset.Unexpanded)); } } if (!presets.empty()) { std::cout << "Available test presets:\n\n"; - cmCMakePresetsFile::PrintPresets(presets); + cmCMakePresetsGraph::PrintPresets(presets); } } -void cmCMakePresetsFile::PrintAllPresets() const +void cmCMakePresetsGraph::PrintAllPresets() const { this->PrintConfigurePresetList(); std::cout << std::endl; diff --git a/Source/cmCMakePresetsFile.h b/Source/cmCMakePresetsGraph.h index 769fb4e..02c506f 100644 --- a/Source/cmCMakePresetsFile.h +++ b/Source/cmCMakePresetsGraph.h @@ -8,12 +8,13 @@ #include <map> #include <memory> #include <string> +#include <unordered_set> #include <utility> #include <vector> #include <cm/optional> -class cmCMakePresetsFile +class cmCMakePresetsGraph { public: enum class ReadFileResult @@ -32,14 +33,18 @@ public: INVALID_VARIABLE, DUPLICATE_PRESETS, CYCLIC_PRESET_INHERITANCE, - USER_PRESET_INHERITANCE, + PRESET_UNREACHABLE_FROM_FILE, INVALID_MACRO_EXPANSION, BUILD_TEST_PRESETS_UNSUPPORTED, + INCLUDE_UNSUPPORTED, + INVALID_INCLUDE, INVALID_CONFIGURE_PRESET, INSTALL_PREFIX_UNSUPPORTED, INVALID_CONDITION, CONDITION_UNSUPPORTED, TOOLCHAIN_FILE_UNSUPPORTED, + CYCLIC_INCLUDE, + INCLUDE_OUTSIDE_PROJECT, }; enum class ArchToolsetStrategy @@ -57,6 +62,15 @@ public: class Condition; + class File + { + public: + std::string Filename; + int Version; + + std::unordered_set<File*> ReachableFiles; + }; + class Preset { public: @@ -77,7 +91,7 @@ public: std::string Name; std::vector<std::string> Inherits; bool Hidden; - bool User; + File* OriginFile; std::string DisplayName; std::string Description; @@ -321,12 +335,11 @@ public: std::vector<std::string> TestPresetOrder; std::string SourceDir; - int Version; - int UserVersion; + std::vector<std::unique_ptr<File>> Files; int GetVersion(const Preset& preset) const { - return preset.User ? this->UserVersion : this->Version; + return preset.OriginFile->Version; } static std::string GetFilename(const std::string& sourceDir); @@ -363,7 +376,7 @@ public: } static void PrintPresets( - const std::vector<const cmCMakePresetsFile::Preset*>& presets); + const std::vector<const cmCMakePresetsGraph::Preset*>& presets); void PrintConfigurePresetList() const; void PrintConfigurePresetList( const std::function<bool(const ConfigurePreset&)>& filter) const; @@ -372,7 +385,22 @@ public: void PrintAllPresets() const; private: + enum class RootType + { + Project, + User, + }; + + enum class ReadReason + { + Root, + Included, + }; + ReadFileResult ReadProjectPresetsInternal(bool allowNoFiles); - ReadFileResult ReadJSONFile(const std::string& filename, bool user); + ReadFileResult ReadJSONFile(const std::string& filename, RootType rootType, + ReadReason readReason, + std::vector<File*>& inProgressFiles, + File*& file); void ClearPresets(); }; diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h new file mode 100644 index 0000000..f7c7349 --- /dev/null +++ b/Source/cmCMakePresetsGraphInternal.h @@ -0,0 +1,163 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <memory> +#include <string> +#include <vector> + +#include <cm3p/json/value.h> + +#include "cmCMakePresetsGraph.h" +#include "cmJSONHelpers.h" + +#define CHECK_OK(expr) \ + do { \ + auto _result = expr; \ + if (_result != ReadFileResult::READ_OK) \ + return _result; \ + } while (false) + +namespace cmCMakePresetsGraphInternal { +enum class ExpandMacroResult +{ + Ok, + Ignore, + Error, +}; + +using MacroExpander = std::function<ExpandMacroResult( + const std::string&, const std::string&, std::string&, int version)>; +} + +class cmCMakePresetsGraph::Condition +{ +public: + virtual ~Condition() = default; + + virtual bool Evaluate( + const std::vector<cmCMakePresetsGraphInternal::MacroExpander>& expanders, + int version, cm::optional<bool>& out) const = 0; + virtual bool IsNull() const { return false; } +}; + +namespace cmCMakePresetsGraphInternal { + +class NullCondition : public cmCMakePresetsGraph::Condition +{ + bool Evaluate(const std::vector<MacroExpander>& /*expanders*/, + int /*version*/, cm::optional<bool>& out) const override + { + out = true; + return true; + } + + bool IsNull() const override { return true; } +}; + +class ConstCondition : public cmCMakePresetsGraph::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& /*expanders*/, + int /*version*/, cm::optional<bool>& out) const override + { + out = this->Value; + return true; + } + + bool Value; +}; + +class EqualsCondition : public cmCMakePresetsGraph::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::string Lhs; + std::string Rhs; +}; + +class InListCondition : public cmCMakePresetsGraph::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::string String; + std::vector<std::string> List; +}; + +class MatchesCondition : public cmCMakePresetsGraph::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::string String; + std::string Regex; +}; + +class AnyAllOfCondition : public cmCMakePresetsGraph::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::vector<std::unique_ptr<Condition>> Conditions; + bool StopValue; +}; + +class NotCondition : public cmCMakePresetsGraph::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::unique_ptr<Condition> SubCondition; +}; + +cmCMakePresetsGraph::ReadFileResult PresetStringHelper( + std::string& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper( + std::vector<std::string>& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper( + cm::optional<bool>& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper( + cm::optional<int>& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper( + std::vector<int>& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult ConfigurePresetsHelper( + std::vector<cmCMakePresetsGraph::ConfigurePreset>& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult BuildPresetsHelper( + std::vector<cmCMakePresetsGraph::BuildPreset>& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult TestPresetsHelper( + std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value); + +cmJSONHelper<std::nullptr_t, cmCMakePresetsGraph::ReadFileResult> VendorHelper( + cmCMakePresetsGraph::ReadFileResult error); + +cmCMakePresetsGraph::ReadFileResult PresetConditionHelper( + std::shared_ptr<cmCMakePresetsGraph::Condition>& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetVectorOneOrMoreStringHelper( + std::vector<std::string>& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper( + std::map<std::string, cm::optional<std::string>>& out, + const Json::Value* value); +} diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx new file mode 100644 index 0000000..ca34124 --- /dev/null +++ b/Source/cmCMakePresetsGraphReadJSON.cxx @@ -0,0 +1,641 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <algorithm> +#include <functional> +#include <map> +#include <string> +#include <unordered_set> +#include <utility> +#include <vector> + +#include <cm/memory> +#include <cm/optional> +#include <cmext/string_view> + +#include <cm3p/json/reader.h> +#include <cm3p/json/value.h> + +#include "cmsys/FStream.hxx" + +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" +#include "cmJSONHelpers.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmVersion.h" + +namespace { +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using CacheVariable = cmCMakePresetsGraph::CacheVariable; +using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; +using BuildPreset = cmCMakePresetsGraph::BuildPreset; +using TestPreset = cmCMakePresetsGraph::TestPreset; +using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; + +constexpr int MIN_VERSION = 1; +constexpr int MAX_VERSION = 4; + +struct CMakeVersion +{ + unsigned int Major = 0; + unsigned int Minor = 0; + unsigned int Patch = 0; +}; + +struct RootPresets +{ + CMakeVersion CMakeMinimumRequired; + std::vector<cmCMakePresetsGraph::ConfigurePreset> ConfigurePresets; + std::vector<cmCMakePresetsGraph::BuildPreset> BuildPresets; + std::vector<cmCMakePresetsGraph::TestPreset> TestPresets; + std::vector<std::string> Include; +}; + +std::unique_ptr<cmCMakePresetsGraphInternal::NotCondition> InvertCondition( + std::unique_ptr<cmCMakePresetsGraph::Condition> condition) +{ + auto retval = cm::make_unique<cmCMakePresetsGraphInternal::NotCondition>(); + retval->SubCondition = std::move(condition); + return retval; +} + +auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); + +auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); + +auto const ConditionStringListHelper = + cmJSONVectorHelper<std::string, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, + ConditionStringHelper); + +auto const ConstConditionHelper = + cmJSONObjectHelper<cmCMakePresetsGraphInternal::ConstCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value, + ConditionBoolHelper, true); + +auto const EqualsConditionHelper = + cmJSONObjectHelper<cmCMakePresetsGraphInternal::EqualsCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs, + ConditionStringHelper, true) + .Bind("rhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Rhs, + ConditionStringHelper, true); + +auto const InListConditionHelper = + cmJSONObjectHelper<cmCMakePresetsGraphInternal::InListCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String, + ConditionStringHelper, true) + .Bind("list"_s, &cmCMakePresetsGraphInternal::InListCondition::List, + ConditionStringListHelper, true); + +auto const MatchesConditionHelper = + cmJSONObjectHelper<cmCMakePresetsGraphInternal::MatchesCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String, + ConditionStringHelper, true) + .Bind("regex"_s, &cmCMakePresetsGraphInternal::MatchesCondition::Regex, + ConditionStringHelper, true); + +ReadFileResult SubConditionHelper( + std::unique_ptr<cmCMakePresetsGraph::Condition>& out, + const Json::Value* value); + +auto const ListConditionVectorHelper = + cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsGraph::Condition>, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, + SubConditionHelper); +auto const AnyAllOfConditionHelper = + cmJSONObjectHelper<cmCMakePresetsGraphInternal::AnyAllOfCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("conditions"_s, + &cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions, + ListConditionVectorHelper); + +auto const NotConditionHelper = + cmJSONObjectHelper<cmCMakePresetsGraphInternal::NotCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("condition"_s, + &cmCMakePresetsGraphInternal::NotCondition::SubCondition, + SubConditionHelper); + +ReadFileResult ConditionHelper( + std::unique_ptr<cmCMakePresetsGraph::Condition>& out, + const Json::Value* value) +{ + if (!value) { + out.reset(); + return ReadFileResult::READ_OK; + } + + if (value->isBool()) { + auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>(); + c->Value = value->asBool(); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (value->isNull()) { + out = cm::make_unique<cmCMakePresetsGraphInternal::NullCondition>(); + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + if (!value->isMember("type")) { + return ReadFileResult::INVALID_CONDITION; + } + + if (!(*value)["type"].isString()) { + return ReadFileResult::INVALID_CONDITION; + } + auto type = (*value)["type"].asString(); + + if (type == "const") { + auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>(); + CHECK_OK(ConstConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (type == "equals" || type == "notEquals") { + auto c = cm::make_unique<cmCMakePresetsGraphInternal::EqualsCondition>(); + CHECK_OK(EqualsConditionHelper(*c, value)); + out = std::move(c); + if (type == "notEquals") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "inList" || type == "notInList") { + auto c = cm::make_unique<cmCMakePresetsGraphInternal::InListCondition>(); + CHECK_OK(InListConditionHelper(*c, value)); + out = std::move(c); + if (type == "notInList") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "matches" || type == "notMatches") { + auto c = + cm::make_unique<cmCMakePresetsGraphInternal::MatchesCondition>(); + CHECK_OK(MatchesConditionHelper(*c, value)); + out = std::move(c); + if (type == "notMatches") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "anyOf" || type == "allOf") { + auto c = + cm::make_unique<cmCMakePresetsGraphInternal::AnyAllOfCondition>(); + c->StopValue = (type == "anyOf"); + CHECK_OK(AnyAllOfConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (type == "not") { + auto c = cm::make_unique<cmCMakePresetsGraphInternal::NotCondition>(); + CHECK_OK(NotConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + } + + return ReadFileResult::INVALID_CONDITION; +} + +ReadFileResult SubConditionHelper( + std::unique_ptr<cmCMakePresetsGraph::Condition>& out, + const Json::Value* value) +{ + std::unique_ptr<cmCMakePresetsGraph::Condition> ptr; + auto result = ConditionHelper(ptr, value); + if (ptr && ptr->IsNull()) { + return ReadFileResult::INVALID_CONDITION; + } + out = std::move(ptr); + return result; +} + +ReadFileResult EnvironmentHelper(cm::optional<std::string>& out, + const Json::Value* value) +{ + if (!value || value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + if (value->isString()) { + out = value->asString(); + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_PRESET; +} + +auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>( + ReadFileResult::NO_VERSION, VersionIntHelper); + +auto const RootVersionHelper = + cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_ROOT) + .Bind("version"_s, VersionHelper, false); + +auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const CMakeVersionHelper = + cmJSONObjectHelper<CMakeVersion, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) + .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) + .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) + .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); + +auto const IncludeHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE); + +auto const IncludeVectorHelper = + cmJSONVectorHelper<std::string, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper); + +auto const RootPresetsHelper = + cmJSONObjectHelper<RootPresets, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) + .Bind<int>("version"_s, nullptr, VersionHelper) + .Bind("configurePresets"_s, &RootPresets::ConfigurePresets, + cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false) + .Bind("buildPresets"_s, &RootPresets::BuildPresets, + cmCMakePresetsGraphInternal::BuildPresetsHelper, false) + .Bind("testPresets"_s, &RootPresets::TestPresets, + cmCMakePresetsGraphInternal::TestPresetsHelper, false) + .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, + CMakeVersionHelper, false) + .Bind("include"_s, &RootPresets::Include, IncludeVectorHelper, false) + .Bind<std::nullptr_t>( + "vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper(ReadFileResult::INVALID_ROOT), + false); +} + +namespace cmCMakePresetsGraphInternal { +cmCMakePresetsGraph::ReadFileResult PresetStringHelper( + std::string& out, const Json::Value* value) +{ + static auto const helper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper( + std::vector<std::string>& out, const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper<std::string, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + cmCMakePresetsGraphInternal::PresetStringHelper); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out, + const Json::Value* value) +{ + static auto const helper = cmJSONBoolHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper( + cm::optional<bool>& out, const Json::Value* value) +{ + static auto const helper = cmJSONOptionalHelper<bool, ReadFileResult>( + ReadFileResult::READ_OK, PresetBoolHelper); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out, + const Json::Value* value) +{ + static auto const helper = cmJSONIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper( + cm::optional<int>& out, const Json::Value* value) +{ + static auto const helper = cmJSONOptionalHelper<int, ReadFileResult>( + ReadFileResult::READ_OK, PresetIntHelper); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper( + std::vector<int>& out, const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper<int, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper); + + return helper(out, value); +} + +cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error) +{ + return [error](std::nullptr_t& /*out*/, + const Json::Value* value) -> ReadFileResult { + if (!value) { + return ReadFileResult::READ_OK; + } + + if (!value->isObject()) { + return error; + } + + return ReadFileResult::READ_OK; + }; +} + +ReadFileResult PresetConditionHelper( + std::shared_ptr<cmCMakePresetsGraph::Condition>& out, + const Json::Value* value) +{ + std::unique_ptr<cmCMakePresetsGraph::Condition> ptr; + auto result = ConditionHelper(ptr, value); + out = std::move(ptr); + return result; +} + +ReadFileResult PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out, + const Json::Value* value) +{ + out.clear(); + if (!value) { + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.push_back(value->asString()); + return ReadFileResult::READ_OK; + } + + return PresetVectorStringHelper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper( + std::map<std::string, cm::optional<std::string>>& out, + const Json::Value* value) +{ + static auto const helper = + cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + EnvironmentHelper); + + return helper(out, value); +} +} + +cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( + const std::string& filename, RootType rootType, ReadReason readReason, + std::vector<File*>& inProgressFiles, File*& file) +{ + ReadFileResult result; + + if (rootType == RootType::Project) { + auto normalizedFilename = cmSystemTools::CollapseFullPath(filename); + + auto normalizedProjectDir = + cmSystemTools::CollapseFullPath(this->SourceDir); + if (!cmSystemTools::IsSubDirectory(normalizedFilename, + normalizedProjectDir)) { + return ReadFileResult::INCLUDE_OUTSIDE_PROJECT; + } + } + + for (auto const& f : this->Files) { + if (cmSystemTools::SameFile(filename, f->Filename)) { + file = f.get(); + auto fileIt = + std::find(inProgressFiles.begin(), inProgressFiles.end(), file); + if (fileIt != inProgressFiles.end()) { + return cmCMakePresetsGraph::ReadFileResult::CYCLIC_INCLUDE; + } + + // Check files included by this file again to make sure they're in the + // project directory. + if (rootType == RootType::Project) { + for (auto* f2 : file->ReachableFiles) { + if (!cmSystemTools::SameFile(filename, f2->Filename)) { + File* file2; + if ((result = this->ReadJSONFile( + f2->Filename, rootType, ReadReason::Included, + inProgressFiles, file2)) != ReadFileResult::READ_OK) { + return result; + } + } + } + } + + return cmCMakePresetsGraph::ReadFileResult::READ_OK; + } + } + + cmsys::ifstream fin(filename.c_str()); + if (!fin) { + return ReadFileResult::FILE_NOT_FOUND; + } + // If there's a BOM, toss it. + cmsys::FStream::ReadBOM(fin); + + Json::Value root; + Json::CharReaderBuilder builder; + Json::CharReaderBuilder::strictMode(&builder.settings_); + if (!Json::parseFromStream(builder, fin, &root, nullptr)) { + return ReadFileResult::JSON_PARSE_ERROR; + } + + int v = 0; + if ((result = RootVersionHelper(v, &root)) != ReadFileResult::READ_OK) { + return result; + } + if (v < MIN_VERSION || v > MAX_VERSION) { + return ReadFileResult::UNRECOGNIZED_VERSION; + } + + // Support for build and test presets added in version 2. + if (v < 2 && + (root.isMember("buildPresets") || root.isMember("testPresets"))) { + return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED; + } + + // Support for include added in version 4. + if (v < 4 && root.isMember("include")) { + return ReadFileResult::INCLUDE_UNSUPPORTED; + } + + RootPresets presets; + if ((result = RootPresetsHelper(presets, &root)) != + ReadFileResult::READ_OK) { + return result; + } + + unsigned int currentMajor = cmVersion::GetMajorVersion(); + unsigned int currentMinor = cmVersion::GetMinorVersion(); + unsigned int currentPatch = cmVersion::GetPatchVersion(); + auto const& required = presets.CMakeMinimumRequired; + if (required.Major > currentMajor || + (required.Major == currentMajor && + (required.Minor > currentMinor || + (required.Minor == currentMinor && + (required.Patch > currentPatch))))) { + return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION; + } + + auto filePtr = cm::make_unique<File>(); + file = filePtr.get(); + this->Files.emplace_back(std::move(filePtr)); + inProgressFiles.emplace_back(file); + file->Filename = filename; + file->Version = v; + file->ReachableFiles.insert(file); + + for (auto& preset : presets.ConfigurePresets) { + preset.OriginFile = file; + if (preset.Name.empty()) { + return ReadFileResult::INVALID_PRESET; + } + + PresetPair<ConfigurePreset> presetPair; + presetPair.Unexpanded = preset; + presetPair.Expanded = cm::nullopt; + if (!this->ConfigurePresets + .emplace(std::make_pair(preset.Name, presetPair)) + .second) { + return ReadFileResult::DUPLICATE_PRESETS; + } + + // Support for installDir presets added in version 3. + if (v < 3 && !preset.InstallDir.empty()) { + return ReadFileResult::INSTALL_PREFIX_UNSUPPORTED; + } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + + // Support for toolchainFile presets added in version 3. + if (v < 3 && !preset.ToolchainFile.empty()) { + return ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED; + } + + this->ConfigurePresetOrder.push_back(preset.Name); + } + + for (auto& preset : presets.BuildPresets) { + preset.OriginFile = file; + if (preset.Name.empty()) { + return ReadFileResult::INVALID_PRESET; + } + + PresetPair<BuildPreset> presetPair; + presetPair.Unexpanded = preset; + presetPair.Expanded = cm::nullopt; + if (!this->BuildPresets.emplace(preset.Name, presetPair).second) { + return ReadFileResult::DUPLICATE_PRESETS; + } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + + this->BuildPresetOrder.push_back(preset.Name); + } + + for (auto& preset : presets.TestPresets) { + preset.OriginFile = file; + if (preset.Name.empty()) { + return ReadFileResult::INVALID_PRESET; + } + + PresetPair<TestPreset> presetPair; + presetPair.Unexpanded = preset; + presetPair.Expanded = cm::nullopt; + if (!this->TestPresets.emplace(preset.Name, presetPair).second) { + return ReadFileResult::DUPLICATE_PRESETS; + } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + + this->TestPresetOrder.push_back(preset.Name); + } + + auto const includeFile = [this, &inProgressFiles, file]( + const std::string& include, RootType rootType2, + ReadReason readReason2) -> ReadFileResult { + ReadFileResult r; + File* includedFile; + if ((r = this->ReadJSONFile(include, rootType2, readReason2, + inProgressFiles, includedFile)) != + ReadFileResult::READ_OK) { + return r; + } + + file->ReachableFiles.insert(includedFile->ReachableFiles.begin(), + includedFile->ReachableFiles.end()); + return ReadFileResult::READ_OK; + }; + + for (auto include : presets.Include) { + if (!cmSystemTools::FileIsFullPath(include)) { + auto directory = cmSystemTools::GetFilenamePath(filename); + include = cmStrCat(directory, '/', include); + } + + if ((result = includeFile(include, rootType, ReadReason::Included)) != + ReadFileResult::READ_OK) { + return result; + } + } + + if (rootType == RootType::User && readReason == ReadReason::Root) { + auto cmakePresetsFilename = GetFilename(this->SourceDir); + if (cmSystemTools::FileExists(cmakePresetsFilename)) { + if ((result = includeFile(cmakePresetsFilename, RootType::Project, + ReadReason::Root)) != + ReadFileResult::READ_OK) { + return result; + } + } + } + + inProgressFiles.pop_back(); + return ReadFileResult::READ_OK; +} diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx new file mode 100644 index 0000000..ef605d1 --- /dev/null +++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx @@ -0,0 +1,75 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <cstddef> +#include <functional> +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include <cm/optional> +#include <cmext/string_view> + +#include <cm3p/json/value.h> + +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" +#include "cmJSONHelpers.h" + +namespace { +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using BuildPreset = cmCMakePresetsGraph::BuildPreset; + +auto const BuildPresetHelper = + cmJSONObjectHelper<BuildPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &BuildPreset::Name, + cmCMakePresetsGraphInternal::PresetStringHelper) + .Bind("inherits"_s, &BuildPreset::Inherits, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("hidden"_s, &BuildPreset::Hidden, + cmCMakePresetsGraphInternal::PresetBoolHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper( + ReadFileResult::INVALID_PRESET), + false) + .Bind("displayName"_s, &BuildPreset::DisplayName, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("description"_s, &BuildPreset::Description, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("environment"_s, &BuildPreset::Environment, + cmCMakePresetsGraphInternal::EnvironmentMapHelper, false) + .Bind("configurePreset"_s, &BuildPreset::ConfigurePreset, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("inheritConfigureEnvironment"_s, + &BuildPreset::InheritConfigureEnvironment, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("jobs"_s, &BuildPreset::Jobs, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("targets"_s, &BuildPreset::Targets, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("configuration"_s, &BuildPreset::Configuration, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("cleanFirst"_s, &BuildPreset::CleanFirst, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("verbose"_s, &BuildPreset::Verbose, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, + cmCMakePresetsGraphInternal::PresetVectorStringHelper, false) + .Bind("condition"_s, &BuildPreset::ConditionEvaluator, + cmCMakePresetsGraphInternal::PresetConditionHelper, false); +} + +namespace cmCMakePresetsGraphInternal { +ReadFileResult BuildPresetsHelper(std::vector<BuildPreset>& out, + const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper<BuildPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + BuildPresetHelper); + + return helper(out, value); +} +} diff --git a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx new file mode 100644 index 0000000..0f44546 --- /dev/null +++ b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx @@ -0,0 +1,228 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <cstddef> +#include <functional> +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include <cm/optional> +#include <cmext/string_view> + +#include <cm3p/json/value.h> + +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" +#include "cmJSONHelpers.h" + +namespace { +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using CacheVariable = cmCMakePresetsGraph::CacheVariable; +using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; +using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; + +ReadFileResult ArchToolsetStrategyHelper( + cm::optional<ArchToolsetStrategy>& out, const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "set") { + out = ArchToolsetStrategy::Set; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "external") { + out = ArchToolsetStrategy::External; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +std::function<ReadFileResult(ConfigurePreset&, const Json::Value*)> +ArchToolsetHelper( + std::string ConfigurePreset::*valueField, + cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField) +{ + auto const objectHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("value", valueField, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); + return [valueField, strategyField, objectHelper]( + ConfigurePreset& out, const Json::Value* value) -> ReadFileResult { + if (!value) { + (out.*valueField).clear(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.*valueField = value->asString(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + return objectHelper(out, value); + } + + return ReadFileResult::INVALID_PRESET; + }; +} + +auto const ArchitectureHelper = ArchToolsetHelper( + &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); +auto const ToolsetHelper = ArchToolsetHelper( + &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); + +auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); + +ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) +{ + if (!value) { + out.clear(); + return ReadFileResult::READ_OK; + } + + if (value->isBool()) { + out = value->asBool() ? "TRUE" : "FALSE"; + return ReadFileResult::READ_OK; + } + + return VariableStringHelper(out, value); +} + +auto const VariableObjectHelper = + cmJSONObjectHelper<CacheVariable, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) + .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) + .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); + +ReadFileResult VariableHelper(cm::optional<CacheVariable>& out, + const Json::Value* value) +{ + if (value->isBool()) { + out = CacheVariable{ + /*Type=*/"BOOL", + /*Value=*/value->asBool() ? "TRUE" : "FALSE", + }; + return ReadFileResult::READ_OK; + } + if (value->isString()) { + out = CacheVariable{ + /*Type=*/"", + /*Value=*/value->asString(), + }; + return ReadFileResult::READ_OK; + } + if (value->isObject()) { + out.emplace(); + return VariableObjectHelper(*out, value); + } + if (value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_VARIABLE; +} + +auto const VariablesHelper = + cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); + +auto const PresetWarningsHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &ConfigurePreset::WarnDev, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); + +auto const PresetErrorsHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &ConfigurePreset::ErrorDev, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); + +auto const PresetDebugHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("output"_s, &ConfigurePreset::DebugOutput, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("find"_s, &ConfigurePreset::DebugFind, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); + +auto const ConfigurePresetHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &ConfigurePreset::Name, + cmCMakePresetsGraphInternal::PresetStringHelper) + .Bind("inherits"_s, &ConfigurePreset::Inherits, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("hidden"_s, &ConfigurePreset::Hidden, + cmCMakePresetsGraphInternal::PresetBoolHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper( + ReadFileResult::INVALID_PRESET), + false) + .Bind("displayName"_s, &ConfigurePreset::DisplayName, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("description"_s, &ConfigurePreset::Description, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("generator"_s, &ConfigurePreset::Generator, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("architecture"_s, ArchitectureHelper, false) + .Bind("toolset"_s, ToolsetHelper, false) + .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("installDir"_s, &ConfigurePreset::InstallDir, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind<std::string>("cmakeExecutable"_s, nullptr, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables, + VariablesHelper, false) + .Bind("environment"_s, &ConfigurePreset::Environment, + cmCMakePresetsGraphInternal::EnvironmentMapHelper, false) + .Bind("warnings"_s, PresetWarningsHelper, false) + .Bind("errors"_s, PresetErrorsHelper, false) + .Bind("debug"_s, PresetDebugHelper, false) + .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, + cmCMakePresetsGraphInternal::PresetConditionHelper, false); +} + +namespace cmCMakePresetsGraphInternal { +ReadFileResult ConfigurePresetsHelper(std::vector<ConfigurePreset>& out, + const Json::Value* value) +{ + static auto const helper = + cmJSONVectorHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + ConfigurePresetHelper); + + return helper(out, value); +} +} diff --git a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx new file mode 100644 index 0000000..4d6474a --- /dev/null +++ b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx @@ -0,0 +1,360 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <cstddef> +#include <functional> +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include <cm/optional> +#include <cmext/string_view> + +#include <cm3p/json/value.h> + +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" +#include "cmJSONHelpers.h" + +namespace { +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using TestPreset = cmCMakePresetsGraph::TestPreset; + +ReadFileResult TestPresetOutputVerbosityHelper( + TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) +{ + if (!value) { + out = TestPreset::OutputOptions::VerbosityEnum::Default; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "default") { + out = TestPreset::OutputOptions::VerbosityEnum::Default; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "verbose") { + out = TestPreset::OutputOptions::VerbosityEnum::Verbose; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "extra") { + out = TestPreset::OutputOptions::VerbosityEnum::Extra; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalOutputVerbosityHelper = + cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum, + ReadFileResult>(ReadFileResult::READ_OK, + TestPresetOutputVerbosityHelper); + +auto const TestPresetOptionalOutputHelper = + cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity, + TestPresetOptionalOutputVerbosityHelper, false) + .Bind("debug"_s, &TestPreset::OutputOptions::Debug, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("outputOnFailure"_s, &TestPreset::OutputOptions::OutputOnFailure, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("quiet"_s, &TestPreset::OutputOptions::Quiet, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("outputLogFile"_s, &TestPreset::OutputOptions::OutputLogFile, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("labelSummary"_s, &TestPreset::OutputOptions::LabelSummary, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("subprojectSummary"_s, + &TestPreset::OutputOptions::SubprojectSummary, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("maxPassedTestOutputSize"_s, + &TestPreset::OutputOptions::MaxPassedTestOutputSize, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("maxFailedTestOutputSize"_s, + &TestPreset::OutputOptions::MaxFailedTestOutputSize, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false)); + +auto const TestPresetOptionalFilterIncludeIndexObjectHelper = + cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions, + ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("stride"_s, &TestPreset::IncludeOptions::IndexOptions::Stride, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("specificTests"_s, + &TestPreset::IncludeOptions::IndexOptions::SpecificTests, + cmCMakePresetsGraphInternal::PresetVectorIntHelper, false)); + +ReadFileResult TestPresetOptionalFilterIncludeIndexHelper( + cm::optional<TestPreset::IncludeOptions::IndexOptions>& out, + const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.emplace(); + out->IndexFile = value->asString(); + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value); + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalFilterIncludeHelper = + cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("name"_s, &TestPreset::IncludeOptions::Name, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("label"_s, &TestPreset::IncludeOptions::Label, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("index"_s, &TestPreset::IncludeOptions::Index, + TestPresetOptionalFilterIncludeIndexHelper, false) + .Bind("useUnion"_s, &TestPreset::IncludeOptions::UseUnion, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)); + +auto const TestPresetOptionalFilterExcludeFixturesHelper = + cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions, + ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("cleanup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Cleanup, + cmCMakePresetsGraphInternal::PresetStringHelper, false)); + +auto const TestPresetOptionalFilterExcludeHelper = + cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("name"_s, &TestPreset::ExcludeOptions::Name, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("label"_s, &TestPreset::ExcludeOptions::Label, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures, + TestPresetOptionalFilterExcludeFixturesHelper, false)); + +ReadFileResult TestPresetExecutionShowOnlyHelper( + TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value) +{ + if (!value || !value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "human") { + out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "json-v1") { + out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionShowOnlyHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum, + ReadFileResult>(ReadFileResult::READ_OK, + TestPresetExecutionShowOnlyHelper); + +ReadFileResult TestPresetExecutionModeHelper( + TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out, + const Json::Value* value) +{ + if (!value) { + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "until-fail") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "until-pass") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "after-timeout") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionRepeatHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions, + ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode, + TestPresetExecutionModeHelper, true) + .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count, + cmCMakePresetsGraphInternal::PresetIntHelper, true)); + +ReadFileResult TestPresetExecutionNoTestsActionHelper( + TestPreset::ExecutionOptions::NoTestsActionEnum& out, + const Json::Value* value) +{ + if (!value) { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "default") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "error") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "ignore") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionNoTestsActionHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum, + ReadFileResult>(ReadFileResult::READ_OK, + TestPresetExecutionNoTestsActionHelper); + +auto const TestPresetExecutionHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("jobs"_s, &TestPreset::ExecutionOptions::Jobs, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("resourceSpecFile"_s, + &TestPreset::ExecutionOptions::ResourceSpecFile, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("testLoad"_s, &TestPreset::ExecutionOptions::TestLoad, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("showOnly"_s, &TestPreset::ExecutionOptions::ShowOnly, + TestPresetOptionalExecutionShowOnlyHelper, false) + .Bind("repeat"_s, &TestPreset::ExecutionOptions::Repeat, + TestPresetOptionalExecutionRepeatHelper, false) + .Bind("interactiveDebugging"_s, + &TestPreset::ExecutionOptions::InteractiveDebugging, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("scheduleRandom"_s, &TestPreset::ExecutionOptions::ScheduleRandom, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("timeout"_s, &TestPreset::ExecutionOptions::Timeout, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("noTestsAction"_s, &TestPreset::ExecutionOptions::NoTestsAction, + TestPresetOptionalExecutionNoTestsActionHelper, false)); + +auto const TestPresetFilterHelper = + cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("include"_s, &TestPreset::FilterOptions::Include, + TestPresetOptionalFilterIncludeHelper, false) + .Bind("exclude"_s, &TestPreset::FilterOptions::Exclude, + TestPresetOptionalFilterExcludeHelper, false)); + +auto const TestPresetHelper = + cmJSONObjectHelper<TestPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &TestPreset::Name, + cmCMakePresetsGraphInternal::PresetStringHelper) + .Bind("inherits"_s, &TestPreset::Inherits, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("hidden"_s, &TestPreset::Hidden, + cmCMakePresetsGraphInternal::PresetBoolHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper( + ReadFileResult::INVALID_PRESET), + false) + .Bind("displayName"_s, &TestPreset::DisplayName, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("description"_s, &TestPreset::Description, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("environment"_s, &TestPreset::Environment, + cmCMakePresetsGraphInternal::EnvironmentMapHelper, false) + .Bind("configurePreset"_s, &TestPreset::ConfigurePreset, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("inheritConfigureEnvironment"_s, + &TestPreset::InheritConfigureEnvironment, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("configuration"_s, &TestPreset::Configuration, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("overwriteConfigurationFile"_s, + &TestPreset::OverwriteConfigurationFile, + cmCMakePresetsGraphInternal::PresetVectorStringHelper, false) + .Bind("output"_s, &TestPreset::Output, TestPresetOptionalOutputHelper, + false) + .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false) + .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper, + false) + .Bind("condition"_s, &TestPreset::ConditionEvaluator, + cmCMakePresetsGraphInternal::PresetConditionHelper, false); +} + +namespace cmCMakePresetsGraphInternal { +cmCMakePresetsGraph::ReadFileResult TestPresetsHelper( + std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper<TestPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + TestPresetHelper); + + return helper(out, value); +} +} diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 647dd87..a1e920e 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -38,7 +38,7 @@ # include <unistd.h> // IWYU pragma: keep #endif -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include "cmCTestBuildAndTestHandler.h" #include "cmCTestBuildHandler.h" #include "cmCTestConfigureHandler.h" @@ -2327,12 +2327,12 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, { const auto workingDirectory = cmSystemTools::GetCurrentWorkingDirectory(); - cmCMakePresetsFile settingsFile; + cmCMakePresetsGraph settingsFile; auto result = settingsFile.ReadProjectPresets(workingDirectory); - if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) { - cmSystemTools::Error(cmStrCat("Could not read presets from ", - workingDirectory, ": ", - cmCMakePresetsFile::ResultToString(result))); + if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { + cmSystemTools::Error( + cmStrCat("Could not read presets from ", workingDirectory, ": ", + cmCMakePresetsGraph::ResultToString(result))); return false; } @@ -2422,15 +2422,15 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Output->Verbosity) { const auto& verbosity = *expandedPreset->Output->Verbosity; switch (verbosity) { - case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: + case cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum:: Extra: this->Impl->ExtraVerbose = true; CM_FALLTHROUGH; - case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: + case cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum:: Verbose: this->Impl->Verbose = true; break; - case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: + case cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum:: Default: default: // leave default settings @@ -2548,13 +2548,13 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, this->Impl->ShowOnly = true; switch (*expandedPreset->Execution->ShowOnly) { - case cmCMakePresetsFile::TestPreset::ExecutionOptions::ShowOnlyEnum:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::ShowOnlyEnum:: JsonV1: this->Impl->Quiet = true; this->Impl->OutputAsJson = true; this->Impl->OutputAsJsonVersion = 1; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions::ShowOnlyEnum:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::ShowOnlyEnum:: Human: // intentional fallthrough (human is the default) default: @@ -2565,15 +2565,15 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Execution->Repeat) { this->Impl->RepeatCount = expandedPreset->Execution->Repeat->Count; switch (expandedPreset->Execution->Repeat->Mode) { - case cmCMakePresetsFile::TestPreset::ExecutionOptions::RepeatOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions:: ModeEnum::UntilFail: this->Impl->RepeatMode = cmCTest::Repeat::UntilFail; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions::RepeatOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions:: ModeEnum::UntilPass: this->Impl->RepeatMode = cmCTest::Repeat::UntilPass; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions::RepeatOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions:: ModeEnum::AfterTimeout: this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout; break; @@ -2599,15 +2599,15 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Execution->NoTestsAction) { switch (*expandedPreset->Execution->NoTestsAction) { - case cmCMakePresetsFile::TestPreset::ExecutionOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions:: NoTestsActionEnum::Error: this->Impl->NoTestsMode = cmCTest::NoTests::Error; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions:: NoTestsActionEnum::Ignore: this->Impl->NoTestsMode = cmCTest::NoTests::Ignore; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions:: NoTestsActionEnum::Default: break; default: diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 338f3c9..d9fb608 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -197,9 +197,10 @@ bool HandleReadCommand(std::vector<std::string> const& args, } // is there a limit? - long sizeLimit = -1; + std::string::size_type sizeLimit = std::string::npos; if (!arguments.Limit.empty()) { - sizeLimit = atoi(arguments.Limit.c_str()); + sizeLimit = + static_cast<std::string::size_type>(atoi(arguments.Limit.c_str())); } // is there an offset? @@ -231,12 +232,9 @@ bool HandleReadCommand(std::vector<std::string> const& args, cmSystemTools::GetLineFromStream(file, line, &has_newline, sizeLimit)) { if (sizeLimit > 0) { sizeLimit = sizeLimit - static_cast<long>(line.size()); - if (has_newline) { + if (has_newline && sizeLimit > 0) { sizeLimit--; } - if (sizeLimit < 0) { - sizeLimit = 0; - } } output += line; if (has_newline) { @@ -1213,9 +1211,14 @@ bool HandleReadElfCommand(std::vector<std::string> const& args, cmELF elf(fileNameArg.c_str()); if (!elf) { - status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg, - "\" that is not a valid ELF file.")); - return false; + if (arguments.Error.empty()) { + status.SetError(cmStrCat("READ_ELF given FILE:\n ", fileNameArg, + "\nthat is not a valid ELF file.")); + return false; + } + status.GetMakefile().AddDefinition(arguments.Error, + "not a valid ELF file"); + return true; } if (!arguments.RPath.empty()) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2a3ef9b..c708eb2 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -29,7 +29,7 @@ #include "cm_sys_stat.h" #include "cmCMakePath.h" -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include "cmCommandLineArgument.h" #include "cmCommands.h" #include "cmDocumentation.h" @@ -1239,43 +1239,43 @@ void cmake::SetArgs(const std::vector<std::string>& args) #if !defined(CMAKE_BOOTSTRAP) if (listPresets != ListPresets::None || !presetName.empty()) { - cmCMakePresetsFile settingsFile; - auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory()); - if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + cmCMakePresetsGraph presetsGraph; + auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory()); + if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { cmSystemTools::Error( cmStrCat("Could not read presets from ", this->GetHomeDirectory(), - ": ", cmCMakePresetsFile::ResultToString(result))); + ": ", cmCMakePresetsGraph::ResultToString(result))); return; } if (listPresets != ListPresets::None) { if (listPresets == ListPresets::Configure) { - this->PrintPresetList(settingsFile); + this->PrintPresetList(presetsGraph); } else if (listPresets == ListPresets::Build) { - settingsFile.PrintBuildPresetList(); + presetsGraph.PrintBuildPresetList(); } else if (listPresets == ListPresets::Test) { - settingsFile.PrintTestPresetList(); + presetsGraph.PrintTestPresetList(); } else if (listPresets == ListPresets::All) { - settingsFile.PrintAllPresets(); + presetsGraph.PrintAllPresets(); } this->SetWorkingMode(WorkingMode::HELP_MODE); return; } - auto preset = settingsFile.ConfigurePresets.find(presetName); - if (preset == settingsFile.ConfigurePresets.end()) { + auto preset = presetsGraph.ConfigurePresets.find(presetName); + if (preset == presetsGraph.ConfigurePresets.end()) { cmSystemTools::Error(cmStrCat("No such preset in ", this->GetHomeDirectory(), ": \"", presetName, '"')); - this->PrintPresetList(settingsFile); + this->PrintPresetList(presetsGraph); return; } if (preset->second.Unexpanded.Hidden) { cmSystemTools::Error(cmStrCat("Cannot use hidden preset in ", this->GetHomeDirectory(), ": \"", presetName, '"')); - this->PrintPresetList(settingsFile); + this->PrintPresetList(presetsGraph); return; } auto const& expandedPreset = preset->second.Expanded; @@ -1319,14 +1319,14 @@ void cmake::SetArgs(const std::vector<std::string>& args) if (!expandedPreset->ArchitectureStrategy || expandedPreset->ArchitectureStrategy == - cmCMakePresetsFile::ArchToolsetStrategy::Set) { + cmCMakePresetsGraph::ArchToolsetStrategy::Set) { if (!this->GeneratorPlatformSet) { this->SetGeneratorPlatform(expandedPreset->Architecture); } } if (!expandedPreset->ToolsetStrategy || expandedPreset->ToolsetStrategy == - cmCMakePresetsFile::ArchToolsetStrategy::Set) { + cmCMakePresetsGraph::ArchToolsetStrategy::Set) { if (!this->GeneratorToolsetSet) { this->SetGeneratorToolset(expandedPreset->Toolset); } @@ -1707,12 +1707,12 @@ bool cmake::CreateAndSetGlobalGenerator(const std::string& name, } #ifndef CMAKE_BOOTSTRAP -void cmake::PrintPresetList(const cmCMakePresetsFile& file) const +void cmake::PrintPresetList(const cmCMakePresetsGraph& graph) const { std::vector<GeneratorInfo> generators; this->GetRegisteredGenerators(generators, false); auto filter = - [&generators](const cmCMakePresetsFile::ConfigurePreset& preset) -> bool { + [&generators](const cmCMakePresetsGraph::ConfigurePreset& preset) -> bool { if (preset.Generator.empty()) { return true; } @@ -1723,7 +1723,7 @@ void cmake::PrintPresetList(const cmCMakePresetsFile& file) const return it != generators.end(); }; - file.PrintConfigurePresetList(filter); + graph.PrintConfigurePresetList(filter); } #endif @@ -3230,12 +3230,12 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory()); - cmCMakePresetsFile settingsFile; + cmCMakePresetsGraph settingsFile; auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory()); - if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { cmSystemTools::Error( cmStrCat("Could not read presets from ", this->GetHomeDirectory(), - ": ", cmCMakePresetsFile::ResultToString(result))); + ": ", cmCMakePresetsGraph::ResultToString(result))); return 1; } diff --git a/Source/cmake.h b/Source/cmake.h index a356e65..b13cc96 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -31,7 +31,7 @@ # include <cm3p/json/value.h> -# include "cmCMakePresetsFile.h" +# include "cmCMakePresetsGraph.h" #endif class cmExternalMakefileProjectGeneratorFactory; @@ -248,7 +248,7 @@ public: #ifndef CMAKE_BOOTSTRAP //! Print list of configure presets - void PrintPresetList(const cmCMakePresetsFile& file) const; + void PrintPresetList(const cmCMakePresetsGraph& graph) const; #endif //! Return the global generator assigned to this instance of cmake @@ -691,7 +691,7 @@ private: std::string GraphVizFile; InstalledFilesMap InstalledFiles; #ifndef CMAKE_BOOTSTRAP - std::map<std::string, cm::optional<cmCMakePresetsFile::CacheVariable>> + std::map<std::string, cm::optional<cmCMakePresetsGraph::CacheVariable>> UnprocessedPresetVariables; std::map<std::string, cm::optional<std::string>> UnprocessedPresetEnvironment; diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index ecb9bf3..dcbf367 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -1265,11 +1265,10 @@ public: } private: - void* GetRealAddress() const + size_t GetRealAddress() const { - return reinterpret_cast<void*>( - static_cast<char*>(this->Address) - - static_cast<char*>(this->BinaryBaseAddress)); + return static_cast<size_t>(static_cast<char*>(this->Address) - + static_cast<char*>(this->BinaryBaseAddress)); } std::string GetFileName(const std::string& path) const; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 6a8520fe..c339fd5 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -4250,9 +4250,9 @@ std::string SystemTools::MakeCidentifier(const std::string& s) // Convenience function around std::getline which removes a trailing carriage // return and can truncate the buffer as needed. Returns true // if any data were read before the end-of-file was reached. -bool SystemTools::GetLineFromStream(std::istream& is, std::string& line, - bool* has_newline /* = 0 */, - long sizeLimit /* = -1 */) +bool SystemTools::GetLineFromStream( + std::istream& is, std::string& line, bool* has_newline /* = 0 */, + std::string::size_type sizeLimit /* = std::string::npos */) { // Start with an empty line. line = ""; @@ -4277,7 +4277,7 @@ bool SystemTools::GetLineFromStream(std::istream& is, std::string& line, } // if we read too much then truncate the buffer - if (sizeLimit >= 0 && line.size() >= static_cast<size_t>(sizeLimit)) { + if (sizeLimit != std::string::npos && line.size() > sizeLimit) { line.resize(sizeLimit); } } diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index dd0cb3b..6684695 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -523,9 +523,9 @@ public: * end-of-file was reached. If the has_newline argument is specified, it will * be true when the line read had a newline character. */ - static bool GetLineFromStream(std::istream& istr, std::string& line, - bool* has_newline = nullptr, - long sizeLimit = -1); + static bool GetLineFromStream( + std::istream& istr, std::string& line, bool* has_newline = nullptr, + std::string::size_type sizeLimit = std::string::npos); /** * Get the parent directory of the directory or file diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index f96bd71..e88a481 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -936,7 +936,8 @@ static bool CheckGetLineFromStream() bool result; file.seekg(0, std::ios::beg); - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); + result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, + std::string::npos); if (!result || line.size() != 5) { std::cerr << "First line does not have five characters: " << line.size() << std::endl; @@ -944,7 +945,8 @@ static bool CheckGetLineFromStream() } file.seekg(0, std::ios::beg); - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); + result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, + std::string::npos); if (!result || line.size() != 5) { std::cerr << "First line does not have five characters after rewind: " << line.size() << std::endl; @@ -953,10 +955,10 @@ static bool CheckGetLineFromStream() bool ret = true; - for (size_t size = 1; size <= 5; ++size) { + for (std::string::size_type size = 1; size <= 5; ++size) { file.seekg(0, std::ios::beg); - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, - static_cast<long>(size)); + result = + kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, size); if (!result || line.size() != size) { std::cerr << "Should have read " << size << " characters but got " << line.size() << std::endl; @@ -999,7 +1001,8 @@ static bool CheckGetLineFromStreamLongLine() bool result; // Read first line. - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); + result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, + std::string::npos); if (!result || line != firstLine) { std::cerr << "First line does not match, expected " << firstLine.size() << " characters, got " << line.size() << std::endl; @@ -1012,7 +1015,8 @@ static bool CheckGetLineFromStreamLongLine() // Read empty line. has_newline = false; - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); + result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, + std::string::npos); if (!result || !line.empty()) { std::cerr << "Expected successful read with an empty line, got " << line.size() << " characters" << std::endl; @@ -1025,7 +1029,8 @@ static bool CheckGetLineFromStreamLongLine() // Read second line. has_newline = false; - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); + result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, + std::string::npos); if (!result || line != secondLine) { std::cerr << "Second line does not match, expected " << secondLine.size() << " characters, got " << line.size() << std::endl; |