/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include #include #include #include #include #include #include #include #include #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& out, const Json::Value* 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 ArchToolsetHelper( std::string ConfigurePreset::*valueField, cm::optional ConfigurePreset::*strategyField) { auto const objectHelper = JSONHelperBuilder::Object(JsonErrors::INVALID_OBJECT, false) .Bind("value", valueField, cmCMakePresetsGraphInternal::PresetStringHelper, false) .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); return [valueField, strategyField, objectHelper](ConfigurePreset& out, const Json::Value* 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& out, const Json::Value* 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& out, const Json::Value* 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, const Json::Value* 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( cmCMakePresetsErrors::INVALID_VARIABLE_OBJECT, false) .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); bool VariableHelper(cm::optional& out, const Json::Value* 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>( cmCMakePresetsErrors::INVALID_PRESET, VariableHelper); auto const PresetWarningsHelper = JSONHelperBuilder::Object( 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( 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( 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( 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( 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("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("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& out, const Json::Value* value, cmJSONState* state) { static auto const helper = JSONHelperBuilder::Vector( cmCMakePresetsErrors::INVALID_PRESETS, ConfigurePresetHelper); return helper(out, value, state); } }