Coverage Report

Created: 2026-09-14 06:43

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 <cassert>
4
#include <functional>
5
#include <map>
6
#include <string>
7
#include <utility>
8
#include <vector>
9
10
#include <cm/optional>
11
#include <cm/string_view>
12
#include <cmext/algorithm>
13
#include <cmext/string_view>
14
15
#include <cm3p/json/value.h>
16
17
#include "cmsys/String.h"
18
19
#include "cmCMakePresetsErrors.h"
20
#include "cmCMakePresetsGraph.h"
21
#include "cmCMakePresetsGraphInternal.h"
22
#include "cmDiagnostics.h"
23
#include "cmJSONHelpers.h"
24
#include "cmStateTypes.h"
25
26
class cmJSONState;
27
28
namespace {
29
using CacheVariable = cmCMakePresetsGraph::CacheVariable;
30
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
31
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
32
using JSONHelperBuilder = cmJSONHelperBuilder;
33
using TraceEnableMode = cmCMakePresetsGraph::TraceEnableMode;
34
using TraceOutputFormat = cmTraceEnums::TraceOutputFormat;
35
36
bool ArchToolsetStrategyHelper(cm::optional<ArchToolsetStrategy>& out,
37
                               Json::Value const* value, cmJSONState* state)
38
3
{
39
3
  if (!value) {
40
3
    out = cm::nullopt;
41
3
    return true;
42
3
  }
43
44
0
  if (!value->isString()) {
45
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
46
0
    return false;
47
0
  }
48
49
0
  if (value->asString() == "set") {
50
0
    out = ArchToolsetStrategy::Set;
51
0
    return true;
52
0
  }
53
54
0
  if (value->asString() == "external") {
55
0
    out = ArchToolsetStrategy::External;
56
0
    return true;
57
0
  }
58
59
0
  cmCMakePresetsErrors::INVALID_PRESET(value, state);
60
0
  return false;
61
0
}
62
63
std::function<bool(ConfigurePreset&, Json::Value const*, cmJSONState*)>
64
ArchToolsetHelper(
65
  std::string ConfigurePreset::*valueField,
66
  cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField)
67
12
{
68
12
  auto const objectHelper =
69
12
    JSONHelperBuilder::Object<ConfigurePreset>(JsonErrors::INVALID_OBJECT,
70
12
                                               false)
71
12
      .Bind("value", valueField,
72
12
            cmCMakePresetsGraphInternal::PresetStringHelper, false)
73
12
      .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false);
74
12
  return [valueField, strategyField,
75
12
          objectHelper](ConfigurePreset& out, Json::Value const* value,
76
208k
                        cmJSONState* state) -> bool {
77
208k
    if (!value) {
78
208k
      (out.*valueField).clear();
79
208k
      out.*strategyField = cm::nullopt;
80
208k
      return true;
81
208k
    }
82
83
120
    if (value->isString()) {
84
117
      out.*valueField = value->asString();
85
117
      out.*strategyField = cm::nullopt;
86
117
      return true;
87
117
    }
88
89
3
    if (value->isObject()) {
90
3
      return objectHelper(out, value, state);
91
3
    }
92
93
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
94
0
    return false;
95
3
  };
96
12
}
97
98
auto const ArchitectureHelper = ArchToolsetHelper(
99
  &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy);
100
auto const ToolsetHelper = ArchToolsetHelper(
101
  &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy);
102
103
bool TraceEnableModeHelper(cm::optional<TraceEnableMode>& out,
104
                           Json::Value const* value, cmJSONState* state)
105
104k
{
106
104k
  if (!value) {
107
104k
    out = cm::nullopt;
108
104k
    return true;
109
104k
  }
110
111
0
  if (!value->isString()) {
112
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
113
0
    return false;
114
0
  }
115
116
0
  if (value->asString() == "on") {
117
0
    out = TraceEnableMode::Default;
118
0
  } else if (value->asString() == "off") {
119
0
    out = TraceEnableMode::Disable;
120
0
  } else if (value->asString() == "expand") {
121
0
    out = TraceEnableMode::Expand;
122
0
  } else {
123
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
124
0
    return false;
125
0
  }
126
127
0
  return true;
128
0
}
129
130
bool TraceOutputFormatHelper(cm::optional<TraceOutputFormat>& out,
131
                             Json::Value const* value, cmJSONState* state)
132
104k
{
133
104k
  if (!value) {
134
104k
    out = cm::nullopt;
135
104k
    return true;
136
104k
  }
137
138
0
  if (!value->isString()) {
139
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
140
0
    return false;
141
0
  }
142
143
0
  if (value->asString() == "human") {
144
0
    out = TraceOutputFormat::Human;
145
0
  } else if (value->asString() == "json-v1") {
146
0
    out = TraceOutputFormat::JSONv1;
147
0
  } else {
148
0
    cmCMakePresetsErrors::INVALID_PRESET(value, state);
149
0
    return false;
150
0
  }
151
152
0
  return true;
153
0
}
154
155
auto const VariableStringHelper = JSONHelperBuilder::String();
156
157
bool VariableValueHelper(std::string& out, Json::Value const* value,
158
                         cmJSONState* state)
159
2.04k
{
160
2.04k
  if (!value) {
161
0
    out.clear();
162
0
    return true;
163
0
  }
164
165
2.04k
  if (value->isBool()) {
166
3
    out = value->asBool() ? "TRUE" : "FALSE";
167
3
    return true;
168
3
  }
169
170
2.04k
  return VariableStringHelper(out, value, state);
171
2.04k
}
172
173
auto const VariableObjectHelper =
174
  JSONHelperBuilder::Object<CacheVariable>(
175
    cmCMakePresetsErrors::INVALID_VARIABLE_OBJECT, false)
176
    .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
177
    .Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
178
179
bool VariableHelper(cm::optional<CacheVariable>& out, Json::Value const* value,
180
                    cmJSONState* state)
181
34.4k
{
182
34.4k
  if (value->isBool()) {
183
621
    out = CacheVariable{
184
621
      /*Type=*/"BOOL",
185
621
      /*Value=*/value->asBool() ? "TRUE" : "FALSE",
186
621
    };
187
621
    return true;
188
621
  }
189
33.8k
  if (value->isString()) {
190
26.2k
    out = CacheVariable{
191
26.2k
      /*Type=*/"",
192
26.2k
      /*Value=*/value->asString(),
193
26.2k
    };
194
26.2k
    return true;
195
26.2k
  }
196
7.55k
  if (value->isObject()) {
197
2.87k
    out.emplace();
198
2.87k
    return VariableObjectHelper(*out, value, state);
199
2.87k
  }
200
4.68k
  if (value->isNull()) {
201
39
    out = cm::nullopt;
202
39
    return true;
203
39
  }
204
4.64k
  cmCMakePresetsErrors::INVALID_VARIABLE(value, state);
205
4.64k
  return false;
206
4.68k
}
207
208
auto const VariablesHelper =
209
  JSONHelperBuilder::Map<cm::optional<CacheVariable>>(
210
    cmCMakePresetsErrors::INVALID_PRESET, VariableHelper);
211
212
template <cmDiagnosticCategory C>
213
cm::string_view GetJSONName()
214
108
{
215
108
  static std::string storage = [] {
216
54
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
54
    std::string out;
218
54
    bool sep = false;
219
666
    for (char const c : in) {
220
666
      if (sep) {
221
30
        out += c;
222
30
        sep = false;
223
636
      } else if (c == '_') {
224
30
        sep = true;
225
606
      } else {
226
606
        out += static_cast<char>(cmsysString_tolower(c));
227
606
      }
228
666
    }
229
54
    return out;
230
54
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)1>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
36
    for (char const c : in) {
220
36
      if (sep) {
221
0
        out += c;
222
0
        sep = false;
223
36
      } else if (c == '_') {
224
0
        sep = true;
225
36
      } else {
226
36
        out += static_cast<char>(cmsysString_tolower(c));
227
36
      }
228
36
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)2>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
60
    for (char const c : in) {
220
60
      if (sep) {
221
0
        out += c;
222
0
        sep = false;
223
60
      } else if (c == '_') {
224
0
        sep = true;
225
60
      } else {
226
60
        out += static_cast<char>(cmsysString_tolower(c));
227
60
      }
228
60
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)3>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
72
    for (char const c : in) {
220
72
      if (sep) {
221
0
        out += c;
222
0
        sep = false;
223
72
      } else if (c == '_') {
224
0
        sep = true;
225
72
      } else {
226
72
        out += static_cast<char>(cmsysString_tolower(c));
227
72
      }
228
72
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)4>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
36
    for (char const c : in) {
220
36
      if (sep) {
221
0
        out += c;
222
0
        sep = false;
223
36
      } else if (c == '_') {
224
0
        sep = true;
225
36
      } else {
226
36
        out += static_cast<char>(cmsysString_tolower(c));
227
36
      }
228
36
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)5>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
168
    for (char const c : in) {
220
168
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
156
      } else if (c == '_') {
224
12
        sep = true;
225
144
      } else {
226
144
        out += static_cast<char>(cmsysString_tolower(c));
227
144
      }
228
168
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)6>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
120
    for (char const c : in) {
220
120
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
108
      } else if (c == '_') {
224
12
        sep = true;
225
96
      } else {
226
96
        out += static_cast<char>(cmsysString_tolower(c));
227
96
      }
228
120
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)7>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
36
    for (char const c : in) {
220
36
      if (sep) {
221
0
        out += c;
222
0
        sep = false;
223
36
      } else if (c == '_') {
224
0
        sep = true;
225
36
      } else {
226
36
        out += static_cast<char>(cmsysString_tolower(c));
227
36
      }
228
36
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)8>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
78
    for (char const c : in) {
220
78
      if (sep) {
221
0
        out += c;
222
0
        sep = false;
223
78
      } else if (c == '_') {
224
0
        sep = true;
225
78
      } else {
226
78
        out += static_cast<char>(cmsysString_tolower(c));
227
78
      }
228
78
    }
229
6
    return out;
230
6
  }();
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:(anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)9>()::{lambda()#1}::operator()() const
Line
Count
Source
215
6
  static std::string storage = [] {
216
6
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
6
    std::string out;
218
6
    bool sep = false;
219
60
    for (char const c : in) {
220
60
      if (sep) {
221
6
        out += c;
222
6
        sep = false;
223
54
      } else if (c == '_') {
224
6
        sep = true;
225
48
      } else {
226
48
        out += static_cast<char>(cmsysString_tolower(c));
227
48
      }
228
60
    }
229
6
    return out;
230
6
  }();
231
108
  return storage;
232
108
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)1>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)2>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)3>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)4>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)5>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)6>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)7>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)8>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
cmCMakePresetsGraphReadJSONConfigurePresets.cxx:std::__1::basic_string_view<char, std::__1::char_traits<char> > (anonymous namespace)::GetJSONName<(cmDiagnostics::DiagnosticCategory)9>()
Line
Count
Source
214
12
{
215
12
  static std::string storage = [] {
216
12
    cm::string_view const in = cmDiagnostics::GetCategoryString(C).substr(4);
217
12
    std::string out;
218
12
    bool sep = false;
219
12
    for (char const c : in) {
220
12
      if (sep) {
221
12
        out += c;
222
12
        sep = false;
223
12
      } else if (c == '_') {
224
12
        sep = true;
225
12
      } else {
226
12
        out += static_cast<char>(cmsysString_tolower(c));
227
12
      }
228
12
    }
229
12
    return out;
230
12
  }();
231
12
  return storage;
232
12
}
233
234
auto const PresetDiagnosticMapHelper =
235
  cmCMakePresetsGraphInternal::PresetMapToBoolHelper<cmDiagnosticCategory>;
236
237
#define BIND_DIAGNOSTIC(C)                                                    \
238
  .Bind(GetJSONName<cmDiagnostics::C>(), &DIAGNOSTIC_MEMBER,                  \
239
        PresetDiagnosticMapHelper, cmDiagnostics::C, false)
240
241
#define DIAGNOSTIC_MEMBER ConfigurePreset::Warnings
242
auto const PresetWarningsHelper =
243
  JSONHelperBuilder::Object<ConfigurePreset>(
244
    JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
245
    .Bind("dev"_s, &ConfigurePreset::WarnDev,
246
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
247
      CM_FOR_EACH_DIAGNOSTIC_CATEGORY(BIND_DIAGNOSTIC)
248
    .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars,
249
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
250
#undef DIAGNOSTIC_MEMBER
251
252
#define DIAGNOSTIC_MEMBER ConfigurePreset::Errors
253
auto const PresetErrorsHelper =
254
  JSONHelperBuilder::Object<ConfigurePreset>(
255
    JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
256
    .Bind("dev"_s, &ConfigurePreset::ErrorDev,
257
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
258
      CM_FOR_EACH_DIAGNOSTIC_CATEGORY(BIND_DIAGNOSTIC);
259
#undef DIAGNOSTIC_MEMBER
260
261
#undef BIND_DIAGNOSTIC
262
263
auto const PresetDebugHelper =
264
  JSONHelperBuilder::Object<ConfigurePreset>(
265
    JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
266
    .Bind("output"_s, &ConfigurePreset::DebugOutput,
267
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
268
    .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile,
269
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
270
    .Bind("find"_s, &ConfigurePreset::DebugFind,
271
          cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
272
273
auto const PresetTraceHelper =
274
  JSONHelperBuilder::Object<ConfigurePreset>(
275
    cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false)
276
    .Bind("mode"_s, &ConfigurePreset::TraceMode, TraceEnableModeHelper, false)
277
    .Bind("format"_s, &ConfigurePreset::TraceFormat, TraceOutputFormatHelper,
278
          false)
279
    .Bind("source"_s, &ConfigurePreset::TraceSource,
280
          cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
281
          false)
282
    .Bind("redirect"_s, &ConfigurePreset::TraceRedirect,
283
          cmCMakePresetsGraphInternal::PresetStringHelper, false);
284
285
auto const ConfigurePresetHelper =
286
  cmCMakePresetsGraphInternal::BindPresetIdentityFields(
287
    JSONHelperBuilder::Object<ConfigurePreset>(
288
      cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false))
289
    .Bind("generator"_s, &ConfigurePreset::Generator,
290
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
291
    .Bind("architecture"_s, ArchitectureHelper, false)
292
    .Bind("toolset"_s, ToolsetHelper, false)
293
    .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile,
294
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
295
    .Bind("graphviz"_s, &ConfigurePreset::GraphVizFile,
296
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
297
    .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir,
298
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
299
    .Bind("installDir"_s, &ConfigurePreset::InstallDir,
300
          cmCMakePresetsGraphInternal::PresetStringHelper, false)
301
    .Bind<std::string>("cmakeExecutable"_s, nullptr,
302
                       cmCMakePresetsGraphInternal::PresetStringHelper, false)
303
    .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables,
304
          VariablesHelper, false)
305
    .Bind("environment"_s, &ConfigurePreset::Environment,
306
          cmCMakePresetsGraphInternal::EnvironmentMapHelper, false)
307
    .Bind("warnings"_s, PresetWarningsHelper, false)
308
    .Bind("errors"_s, PresetErrorsHelper, false)
309
    .Bind("debug"_s, PresetDebugHelper, false)
310
    .Bind("trace"_s, PresetTraceHelper, false);
311
}
312
313
namespace cmCMakePresetsGraphInternal {
314
cm::string_view GetDiagnosticJSONName(cmDiagnosticCategory category)
315
0
{
316
0
  static cm::string_view const names[] = {
317
0
    "none"_s, // CMD_NONE
318
0
#define DIAGNOSTIC_JSON_NAME(C) GetJSONName<cmDiagnostics::C>(),
319
0
    CM_FOR_EACH_DIAGNOSTIC_CATEGORY(DIAGNOSTIC_JSON_NAME)
320
0
#undef DIAGNOSTIC_JSON_NAME
321
0
  };
322
0
  assert(category > 0 && category < cmDiagnostics::CategoryCount);
323
0
  return names[category];
324
0
}
325
326
bool ConfigurePresetsHelper(std::vector<ConfigurePreset>& out,
327
                            Json::Value const* value, cmJSONState* state)
328
26.6k
{
329
26.6k
  static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>(
330
26.6k
    cmCMakePresetsErrors::INVALID_PRESETS, ConfigurePresetHelper);
331
332
26.6k
  return helper(out, value, state);
333
26.6k
}
334
335
bool CheckDiagnostics(cmJSONState* state, int version,
336
                      std::map<cmDiagnosticCategory, bool> values,
337
                      cm::string_view group)
338
94.8k
{
339
  // NOLINTNEXTLINE(readability-use-anyofallof)
340
94.8k
  for (auto const& i : values) {
341
0
    assert(i.first > 0 && i.first < cmDiagnostics::CategoryCount);
342
0
    int const minVersion = cmDiagnostics::CategoryInfo[i.first].PresetVersion;
343
0
    if (version < minVersion) {
344
0
      cm::string_view dn = GetDiagnosticJSONName(i.first);
345
0
      cmCMakePresetsErrors::DIAGNOSTIC_UNSUPPORTED(dn, group, minVersion,
346
0
                                                   state);
347
0
      return false;
348
0
    }
349
0
  }
350
351
94.8k
  return true;
352
94.8k
}
353
354
bool CheckDiagnostics(cmJSONState* state, int version,
355
                      cmCMakePresetsGraph::ConfigurePreset& preset)
356
47.4k
{
357
  // Check for diagnostics added in later schemes.
358
47.4k
  if (!CheckDiagnostics(state, version, preset.Warnings, "warnings"_s) ||
359
47.4k
      !CheckDiagnostics(state, version, preset.Errors, "errors"_s)) {
360
0
    return false;
361
0
  }
362
363
47.4k
  if (version < 12) {
364
    // Handle 'dev'.
365
46.8k
    if (preset.WarnDev) {
366
0
      preset.Warnings.emplace(cmDiagnostics::CMD_AUTHOR, *preset.WarnDev);
367
0
    }
368
46.8k
    if (preset.ErrorDev) {
369
0
      preset.Errors.emplace(cmDiagnostics::CMD_AUTHOR, *preset.ErrorDev);
370
0
    }
371
372
    // Check for diagnostics only present as warnings before v12.
373
46.8k
    constexpr cmDiagnosticCategory unsupportedErrors[] = {
374
46.8k
      cmDiagnostics::CMD_UNINITIALIZED,
375
46.8k
      cmDiagnostics::CMD_UNUSED_CLI,
376
46.8k
    };
377
378
93.7k
    for (cmDiagnosticCategory c : unsupportedErrors) {
379
93.7k
      if (cm::contains(preset.Errors, c)) {
380
0
        cm::string_view dn = GetDiagnosticJSONName(c);
381
0
        cmCMakePresetsErrors::DIAGNOSTIC_UNSUPPORTED(dn, "errors"_s, 12,
382
0
                                                     state);
383
0
        return false;
384
0
      }
385
93.7k
    }
386
46.8k
  } else {
387
    // Check for diagnostics removed in v12.
388
564
    if (preset.WarnDev) {
389
0
      cmCMakePresetsErrors::DIAGNOSTIC_REMOVED("dev"_s, "warnings"_s, 11,
390
0
                                               state);
391
0
      return false;
392
0
    }
393
564
    if (preset.ErrorDev) {
394
0
      cmCMakePresetsErrors::DIAGNOSTIC_REMOVED("dev"_s, "errors"_s, 11, state);
395
0
      return false;
396
0
    }
397
564
  }
398
399
47.4k
  return true;
400
47.4k
}
401
}