Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include <cstddef>
4
#include <functional>
5
#include <map>
6
#include <memory>
7
#include <string>
8
#include <vector>
9
10
#include <cm/optional>
11
#include <cmext/string_view>
12
13
#include <cm3p/json/value.h>
14
15
#include "cmCMakePresetsErrors.h"
16
#include "cmCMakePresetsGraph.h"
17
#include "cmCMakePresetsGraphInternal.h"
18
#include "cmJSONHelpers.h"
19
#include "cmStateTypes.h"
20
21
class cmJSONState;
22
23
namespace {
24
using CacheVariable = cmCMakePresetsGraph::CacheVariable;
25
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
26
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
27
using JSONHelperBuilder = cmJSONHelperBuilder;
28
using TraceEnableMode = cmCMakePresetsGraph::TraceEnableMode;
29
using TraceOutputFormat = cmTraceEnums::TraceOutputFormat;
30
31
bool ArchToolsetStrategyHelper(cm::optional<ArchToolsetStrategy>& out,
32
                               Json::Value const* value, cmJSONState* state)
33
0
{
34
0
  if (!value) {
35
0
    out = cm::nullopt;
36
0
    return true;
37
0
  }
38
39
0
  if (!value->isString()) {
40
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
41
0
    return false;
42
0
  }
43
44
0
  if (value->asString() == "set") {
45
0
    out = ArchToolsetStrategy::Set;
46
0
    return true;
47
0
  }
48
49
0
  if (value->asString() == "external") {
50
0
    out = ArchToolsetStrategy::External;
51
0
    return true;
52
0
  }
53
54
0
  cmCMakePresetsErrors::INVALID_PRESET(value, state);
55
0
  return false;
56
0
}
57
58
std::function<bool(ConfigurePreset&, Json::Value const*, cmJSONState*)>
59
ArchToolsetHelper(
60
  std::string ConfigurePreset::*valueField,
61
  cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField)
62
8
{
63
8
  auto const objectHelper =
64
8
    JSONHelperBuilder::Object<ConfigurePreset>(JsonErrors::INVALID_OBJECT,
65
8
                                               false)
66
8
      .Bind("value", valueField,
67
8
            cmCMakePresetsGraphInternal::PresetStringHelper, false)
68
8
      .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false);
69
8
  return [valueField, strategyField,
70
8
          objectHelper](ConfigurePreset& out, Json::Value const* value,
71
8
                        cmJSONState* state) -> bool {
72
0
    if (!value) {
73
0
      (out.*valueField).clear();
74
0
      out.*strategyField = cm::nullopt;
75
0
      return true;
76
0
    }
77
78
0
    if (value->isString()) {
79
0
      out.*valueField = value->asString();
80
0
      out.*strategyField = cm::nullopt;
81
0
      return true;
82
0
    }
83
84
0
    if (value->isObject()) {
85
0
      return objectHelper(out, value, state);
86
0
    }
87
88
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
89
0
    return false;
90
0
  };
91
8
}
92
93
auto const ArchitectureHelper = ArchToolsetHelper(
94
  &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy);
95
auto const ToolsetHelper = ArchToolsetHelper(
96
  &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy);
97
98
bool TraceEnableModeHelper(cm::optional<TraceEnableMode>& out,
99
                           Json::Value const* value, cmJSONState* state)
100
0
{
101
0
  if (!value) {
102
0
    out = cm::nullopt;
103
0
    return true;
104
0
  }
105
106
0
  if (!value->isString()) {
107
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
108
0
    return false;
109
0
  }
110
111
0
  if (value->asString() == "on") {
112
0
    out = TraceEnableMode::Default;
113
0
  } else if (value->asString() == "off") {
114
0
    out = TraceEnableMode::Disable;
115
0
  } else if (value->asString() == "expand") {
116
0
    out = TraceEnableMode::Expand;
117
0
  } else {
118
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
119
0
    return false;
120
0
  }
121
122
0
  return true;
123
0
}
124
125
bool TraceOutputFormatHelper(cm::optional<TraceOutputFormat>& out,
126
                             Json::Value const* value, cmJSONState* state)
127
0
{
128
0
  if (!value) {
129
0
    out = cm::nullopt;
130
0
    return true;
131
0
  }
132
133
0
  if (!value->isString()) {
134
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
135
0
    return false;
136
0
  }
137
138
0
  if (value->asString() == "human") {
139
0
    out = TraceOutputFormat::Human;
140
0
  } else if (value->asString() == "json-v1") {
141
0
    out = TraceOutputFormat::JSONv1;
142
0
  } else {
143
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
144
0
    return false;
145
0
  }
146
147
0
  return true;
148
0
}
149
150
auto const VariableStringHelper = JSONHelperBuilder::String();
151
152
bool VariableValueHelper(std::string& out, Json::Value const* value,
153
                         cmJSONState* state)
154
0
{
155
0
  if (!value) {
156
0
    out.clear();
157
0
    return true;
158
0
  }
159
160
0
  if (value->isBool()) {
161
0
    out = value->asBool() ? "TRUE" : "FALSE";
162
0
    return true;
163
0
  }
164
165
0
  return VariableStringHelper(out, value, state);
166
0
}
167
168
auto const VariableObjectHelper =
169
  JSONHelperBuilder::Object<CacheVariable>(
170
    cmCMakePresetsErrors::INVALID_VARIABLE_OBJECT, false)
171
    .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
172
    .Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
173
174
bool VariableHelper(cm::optional<CacheVariable>& out, Json::Value const* value,
175
                    cmJSONState* state)
176
0
{
177
0
  if (value->isBool()) {
178
0
    out = CacheVariable{
179
0
      /*Type=*/"BOOL",
180
0
      /*Value=*/value->asBool() ? "TRUE" : "FALSE",
181
0
    };
182
0
    return true;
183
0
  }
184
0
  if (value->isString()) {
185
0
    out = CacheVariable{
186
0
      /*Type=*/"",
187
0
      /*Value=*/value->asString(),
188
0
    };
189
0
    return true;
190
0
  }
191
0
  if (value->isObject()) {
192
0
    out.emplace();
193
0
    return VariableObjectHelper(*out, value, state);
194
0
  }
195
0
  if (value->isNull()) {
196
0
    out = cm::nullopt;
197
0
    return true;
198
0
  }
199
0
  cmCMakePresetsErrors::INVALID_VARIABLE(value, state);
200
0
  return false;
201
0
}
202
203
auto const VariablesHelper =
204
  JSONHelperBuilder::Map<cm::optional<CacheVariable>>(
205
    cmCMakePresetsErrors::INVALID_PRESET, VariableHelper);
206
207
auto const PresetWarningsHelper =
208
  JSONHelperBuilder::Object<ConfigurePreset>(
209
    JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
210
    .Bind("dev"_s, &ConfigurePreset::WarnDev,
211
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
212
    .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated,
213
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
214
    .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized,
215
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
216
    .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli,
217
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
218
    .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars,
219
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
220
221
auto const PresetErrorsHelper =
222
  JSONHelperBuilder::Object<ConfigurePreset>(
223
    JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
224
    .Bind("dev"_s, &ConfigurePreset::ErrorDev,
225
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
226
    .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated,
227
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
228
229
auto const PresetDebugHelper =
230
  JSONHelperBuilder::Object<ConfigurePreset>(
231
    JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
232
    .Bind("output"_s, &ConfigurePreset::DebugOutput,
233
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
234
    .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile,
235
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
236
    .Bind("find"_s, &ConfigurePreset::DebugFind,
237
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
238
239
auto const PresetTraceHelper =
240
  JSONHelperBuilder::Object<ConfigurePreset>(
241
    cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
242
    .Bind("mode"_s, &ConfigurePreset::TraceMode, TraceEnableModeHelper, false)
243
    .Bind("format"_s, &ConfigurePreset::TraceFormat, TraceOutputFormatHelper,
244
          false)
245
    .Bind("source"_s, &ConfigurePreset::TraceSource,
246
          cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
247
          false)
248
    .Bind("redirect"_s, &ConfigurePreset::TraceRedirect,
249
          cmCMakePresetsGraphInternal::PresetStringHelper, false);
250
251
auto const ConfigurePresetHelper =
252
  JSONHelperBuilder::Object<ConfigurePreset>(
253
    cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
254
    .Bind("name"_s, &ConfigurePreset::Name,
255
          cmCMakePresetsGraphInternal::PresetNameHelper)
256
    .Bind("inherits"_s, &ConfigurePreset::Inherits,
257
          cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
258
          false)
259
    .Bind("hidden"_s, &ConfigurePreset::Hidden,
260
          cmCMakePresetsGraphInternal::PresetBoolHelper, false)
261
    .Bind<std::nullptr_t>("vendor"_s, nullptr,
262
                          cmCMakePresetsGraphInternal::VendorHelper(
263
                            cmCMakePresetsErrors::INVALID_PRESET),
264
                          false)
265
    .Bind("displayName"_s, &ConfigurePreset::DisplayName,
266
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
267
    .Bind("description"_s, &ConfigurePreset::Description,
268
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
269
    .Bind("generator"_s, &ConfigurePreset::Generator,
270
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
271
    .Bind("architecture"_s, ArchitectureHelper, false)
272
    .Bind("toolset"_s, ToolsetHelper, false)
273
    .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile,
274
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
275
    .Bind("graphviz"_s, &ConfigurePreset::GraphVizFile,
276
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
277
    .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir,
278
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
279
    .Bind("installDir"_s, &ConfigurePreset::InstallDir,
280
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
281
    .Bind<std::string>("cmakeExecutable"_s, nullptr,
282
                       cmCMakePresetsGraphInternal::PresetStringHelper, false)
283
    .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables,
284
          VariablesHelper, false)
285
    .Bind("environment"_s, &ConfigurePreset::Environment,
286
          cmCMakePresetsGraphInternal::EnvironmentMapHelper, false)
287
    .Bind("warnings"_s, PresetWarningsHelper, false)
288
    .Bind("errors"_s, PresetErrorsHelper, false)
289
    .Bind("debug"_s, PresetDebugHelper, false)
290
    .Bind("trace"_s, PresetTraceHelper, false)
291
    .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator,
292
          cmCMakePresetsGraphInternal::PresetConditionHelper, false);
293
}
294
295
namespace cmCMakePresetsGraphInternal {
296
bool ConfigurePresetsHelper(std::vector<ConfigurePreset>& out,
297
                            Json::Value const* value, cmJSONState* state)
298
0
{
299
0
  static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>(
300
0
    cmCMakePresetsErrors::INVALID_PRESETS, ConfigurePresetHelper);
301
302
0
  return helper(out, value, state);
303
0
}
304
}