| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst 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 "cmCMakePresetsErrors.h" | |
| #include "cmCMakePresetsGraph.h" | |
| #include "cmCMakePresetsGraphInternal.h" | |
| #include "cmJSONHelpers.h" | |
| #include "cmStateTypes.h" | |
| class cmJSONState; | |
| namespace { | |
| using CacheVariable = cmCMakePresetsGraph::CacheVariable; | |
| using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; | |
| using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; | |
| using JSONHelperBuilder = cmJSONHelperBuilder; | |
| using TraceEnableMode = cmCMakePresetsGraph::TraceEnableMode; | |
| using TraceOutputFormat = cmTraceEnums::TraceOutputFormat; | |
| bool ArchToolsetStrategyHelper(cm::optional<ArchToolsetStrategy>& out, | |
| Json::Value const* value, cmJSONState* state) | |
| { | |
| if (!value) { | |
| out = cm::nullopt; | |
| return true; | |
| } | |
| if (!value->isString()) { | |
| cmCMakePresetsErrors::INVALID_PRESET(value, state); | |
| return false; | |
| } | |
| if (value->asString() == "set") { | |
| out = ArchToolsetStrategy::Set; | |
| return true; | |
| } | |
| if (value->asString() == "external") { | |
| out = ArchToolsetStrategy::External; | |
| return true; | |
| } | |
| cmCMakePresetsErrors::INVALID_PRESET(value, state); | |
| return false; | |
| } | |
| std::function<bool(ConfigurePreset&, Json::Value const*, cmJSONState*)> | |
| ArchToolsetHelper( | |
| std::string ConfigurePreset::*valueField, | |
| cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField) | |
| { | |
| auto const objectHelper = | |
| JSONHelperBuilder::Object<ConfigurePreset>(JsonErrors::INVALID_OBJECT, | |
| false) | |
| .Bind("value", valueField, | |
| cmCMakePresetsGraphInternal::PresetStringHelper, false) | |
| .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); | |
| return [valueField, strategyField, | |
| objectHelper](ConfigurePreset& out, Json::Value const* value, | |
| cmJSONState* state) -> bool { | |
| if (!value) { | |
| (out.*valueField).clear(); | |
| out.*strategyField = cm::nullopt; | |
| return true; | |
| } | |
| if (value->isString()) { | |
| out.*valueField = value->asString(); | |
| out.*strategyField = cm::nullopt; | |
| return true; | |
| } | |
| if (value->isObject()) { | |
| return objectHelper(out, value, state); | |
| } | |
| cmCMakePresetsErrors::INVALID_PRESET(value, state); | |
| return false; | |
| }; | |
| } | |
| auto const ArchitectureHelper = ArchToolsetHelper( | |
| &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); | |
| auto const ToolsetHelper = ArchToolsetHelper( | |
| &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); | |
| bool TraceEnableModeHelper(cm::optional<TraceEnableMode>& out, | |
| Json::Value const* value, cmJSONState* state) | |
| { | |
| if (!value) { | |
| out = cm::nullopt; | |
| return true; | |
| } | |
| if (!value->isString()) { | |
| cmCMakePresetsErrors::INVALID_PRESET(value, state); | |
| return false; | |
| } | |
| if (value->asString() == "on") { | |
| out = TraceEnableMode::Default; | |
| } else if (value->asString() == "off") { | |
| out = TraceEnableMode::Disable; | |
| } else if (value->asString() == "expand") { | |
| out = TraceEnableMode::Expand; | |
| } else { | |
| cmCMakePresetsErrors::INVALID_PRESET(value, state); | |
| return false; | |
| } | |
| return true; | |
| } | |
| bool TraceOutputFormatHelper(cm::optional<TraceOutputFormat>& out, | |
| Json::Value const* value, cmJSONState* state) | |
| { | |
| if (!value) { | |
| out = cm::nullopt; | |
| return true; | |
| } | |
| if (!value->isString()) { | |
| cmCMakePresetsErrors::INVALID_PRESET(value, state); | |
| return false; | |
| } | |
| if (value->asString() == "human") { | |
| out = TraceOutputFormat::Human; | |
| } else if (value->asString() == "json-v1") { | |
| out = TraceOutputFormat::JSONv1; | |
| } else { | |
| cmCMakePresetsErrors::INVALID_PRESET(value, state); | |
| return false; | |
| } | |
| return true; | |
| } | |
| auto const VariableStringHelper = JSONHelperBuilder::String(); | |
| bool VariableValueHelper(std::string& out, Json::Value const* value, | |
| cmJSONState* state) | |
| { | |
| if (!value) { | |
| out.clear(); | |
| return true; | |
| } | |
| if (value->isBool()) { | |
| out = value->asBool() ? "TRUE" : "FALSE"; | |
| return true; | |
| } | |
| return VariableStringHelper(out, value, state); | |
| } | |
| auto const VariableObjectHelper = | |
| JSONHelperBuilder::Object<CacheVariable>( | |
| cmCMakePresetsErrors::INVALID_VARIABLE_OBJECT, false) | |
| .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) | |
| .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); | |
| bool VariableHelper(cm::optional<CacheVariable>& out, Json::Value const* value, | |
| cmJSONState* state) | |
| { | |
| if (value->isBool()) { | |
| out = CacheVariable{ | |
| /*Type=*/"BOOL", | |
| /*Value=*/value->asBool() ? "TRUE" : "FALSE", | |
| }; | |
| return true; | |
| } | |
| if (value->isString()) { | |
| out = CacheVariable{ | |
| /*Type=*/"", | |
| /*Value=*/value->asString(), | |
| }; | |
| return true; | |
| } | |
| if (value->isObject()) { | |
| out.emplace(); | |
| return VariableObjectHelper(*out, value, state); | |
| } | |
| if (value->isNull()) { | |
| out = cm::nullopt; | |
| return true; | |
| } | |
| cmCMakePresetsErrors::INVALID_VARIABLE(value, state); | |
| return false; | |
| } | |
| auto const VariablesHelper = | |
| JSONHelperBuilder::Map<cm::optional<CacheVariable>>( | |
| cmCMakePresetsErrors::INVALID_PRESET, VariableHelper); | |
| auto const PresetWarningsHelper = | |
| JSONHelperBuilder::Object<ConfigurePreset>( | |
| JsonErrors::INVALID_NAMED_OBJECT_KEY, 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 = | |
| JSONHelperBuilder::Object<ConfigurePreset>( | |
| JsonErrors::INVALID_NAMED_OBJECT_KEY, false) | |
| .Bind("dev"_s, &ConfigurePreset::ErrorDev, | |
| cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) | |
| .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, | |
| cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); | |
| auto const PresetDebugHelper = | |
| JSONHelperBuilder::Object<ConfigurePreset>( | |
| JsonErrors::INVALID_NAMED_OBJECT_KEY, 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 PresetTraceHelper = | |
| JSONHelperBuilder::Object<ConfigurePreset>( | |
| cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false) | |
| .Bind("mode"_s, &ConfigurePreset::TraceMode, TraceEnableModeHelper, false) | |
| .Bind("format"_s, &ConfigurePreset::TraceFormat, TraceOutputFormatHelper, | |
| false) | |
| .Bind("source"_s, &ConfigurePreset::TraceSource, | |
| cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, | |
| false) | |
| .Bind("redirect"_s, &ConfigurePreset::TraceRedirect, | |
| cmCMakePresetsGraphInternal::PresetStringHelper, false); | |
| auto const ConfigurePresetHelper = | |
| JSONHelperBuilder::Object<ConfigurePreset>( | |
| cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false) | |
| .Bind("name"_s, &ConfigurePreset::Name, | |
| cmCMakePresetsGraphInternal::PresetNameHelper) | |
| .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( | |
| cmCMakePresetsErrors::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("graphviz"_s, &ConfigurePreset::GraphVizFile, | |
| 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("trace"_s, PresetTraceHelper, false) | |
| .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, | |
| cmCMakePresetsGraphInternal::PresetConditionHelper, false); | |
| } | |
| namespace cmCMakePresetsGraphInternal { | |
| bool ConfigurePresetsHelper(std::vector<ConfigurePreset>& out, | |
| Json::Value const* value, cmJSONState* state) | |
| { | |
| static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>( | |
| cmCMakePresetsErrors::INVALID_PRESETS, ConfigurePresetHelper); | |
| return helper(out, value, state); | |
| } | |
| } |