Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCMakePresetsErrors.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 "cmConfigure.h" // IWYU pragma: keep
4
5
#include "cmCMakePresetsErrors.h"
6
7
#include <functional>
8
#include <utility>
9
#include <vector>
10
11
#include <cm3p/json/value.h>
12
13
#include "cmJSONHelpers.h"
14
#include "cmJSONState.h"
15
#include "cmStringAlgorithms.h"
16
17
namespace cmCMakePresetsErrors {
18
Json::Value const* getPreset(cmJSONState* state)
19
0
{
20
0
  if (state->parseStack.size() < 2) {
21
0
    return nullptr;
22
0
  }
23
0
  std::string firstKey = state->parseStack[0].first;
24
0
  if (firstKey == "configurePresets" || firstKey == "packagePresets" ||
25
0
      firstKey == "buildPresets" || firstKey == "testPresets") {
26
0
    return state->parseStack[1].second;
27
0
  }
28
0
  return nullptr;
29
0
}
30
31
std::string getPresetName(cmJSONState* state)
32
0
{
33
0
  Json::Value const* preset = getPreset(state);
34
0
  if (preset && preset->isMember("name")) {
35
0
    return preset->operator[]("name").asString();
36
0
  }
37
0
  return "";
38
0
}
39
40
std::string getVariableName(cmJSONState* state)
41
0
{
42
0
  std::string var = state->key_after("cacheVariables");
43
0
  std::string errMsg = cmStrCat("variable \"", var, '"');
44
0
  errMsg = cmStrCat(errMsg, " for preset \"", getPresetName(state), '"');
45
0
  return errMsg;
46
0
}
47
48
void FILE_NOT_FOUND(std::string const& filename, cmJSONState* state)
49
0
{
50
0
  state->AddError(cmStrCat("File not found: ", filename));
51
0
}
52
53
void INVALID_ROOT(Json::Value const* value, cmJSONState* state)
54
0
{
55
0
  state->AddErrorAtValue("Invalid root object", value);
56
0
}
57
58
void NO_VERSION(Json::Value const* value, cmJSONState* state)
59
0
{
60
0
  state->AddErrorAtValue("No \"version\" field", value);
61
0
}
62
63
void INVALID_VERSION(Json::Value const* value, cmJSONState* state)
64
0
{
65
0
  state->AddErrorAtValue("Invalid \"version\" field", value);
66
0
}
67
68
void UNRECOGNIZED_VERSION(Json::Value const* value, cmJSONState* state)
69
0
{
70
0
  state->AddErrorAtValue("Unrecognized \"version\" field", value);
71
0
}
72
73
void INVALID_PRESETS(Json::Value const* value, cmJSONState* state)
74
0
{
75
0
  state->AddErrorAtValue("Invalid \"configurePresets\" field", value);
76
0
}
77
78
void INVALID_PRESET(Json::Value const* value, cmJSONState* state)
79
0
{
80
0
  state->AddErrorAtValue("Invalid preset", value);
81
0
}
82
83
void INVALID_PRESET_NAMED(std::string const& presetName, cmJSONState* state)
84
0
{
85
0
  state->AddError(cmStrCat("Invalid preset: \"", presetName, '"'));
86
0
}
87
88
void INVALID_VARIABLE(Json::Value const* value, cmJSONState* state)
89
0
{
90
0
  std::string var = cmCMakePresetsErrors::getVariableName(state);
91
0
  state->AddErrorAtValue(cmStrCat("Invalid CMake ", var), value);
92
0
}
93
94
void DUPLICATE_PRESETS(std::string const& presetName, cmJSONState* state)
95
0
{
96
0
  state->AddError(cmStrCat("Duplicate preset: \"", presetName, '"'));
97
0
}
98
99
void CYCLIC_PRESET_INHERITANCE(std::string const& presetName,
100
                               cmJSONState* state)
101
102
0
{
103
0
  state->AddError(
104
0
    cmStrCat("Cyclic preset inheritance for preset \"", presetName, '"'));
105
0
}
106
107
void INHERITED_PRESET_UNREACHABLE_FROM_FILE(std::string const& presetName,
108
                                            cmJSONState* state)
109
0
{
110
0
  state->AddError(cmStrCat("Inherited preset \"", presetName,
111
0
                           "\" is unreachable from preset's file"));
112
0
}
113
114
void CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(std::string const& presetName,
115
                                            cmJSONState* state)
116
0
{
117
0
  state->AddError(cmStrCat("Configure preset \"", presetName,
118
0
                           "\" is unreachable from preset's file"));
119
0
}
120
121
void INVALID_MACRO_EXPANSION(std::string const& presetName, cmJSONState* state)
122
0
{
123
0
  state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, '"'));
124
0
}
125
126
void BUILD_TEST_PRESETS_UNSUPPORTED(Json::Value const*, cmJSONState* state)
127
0
{
128
0
  state->AddError("File version must be 2 or higher for build and test preset "
129
0
                  "support");
130
0
}
131
132
void PACKAGE_PRESETS_UNSUPPORTED(Json::Value const*, cmJSONState* state)
133
0
{
134
0
  state->AddError(
135
0
    "File version must be 6 or higher for package preset support");
136
0
}
137
138
void WORKFLOW_PRESETS_UNSUPPORTED(Json::Value const*, cmJSONState* state)
139
0
{
140
0
  state->AddError(
141
0
    "File version must be 6 or higher for workflow preset support");
142
0
}
143
144
void INCLUDE_UNSUPPORTED(Json::Value const*, cmJSONState* state)
145
0
{
146
0
  state->AddError("File version must be 4 or higher for include support");
147
0
}
148
149
void INVALID_INCLUDE(Json::Value const* value, cmJSONState* state)
150
0
{
151
0
  state->AddErrorAtValue("Invalid \"include\" field", value);
152
0
}
153
154
void INVALID_CONFIGURE_PRESET(std::string const& presetName,
155
                              cmJSONState* state)
156
0
{
157
0
  state->AddError(
158
0
    cmStrCat(R"(Invalid "configurePreset": ")", presetName, '"'));
159
0
}
160
161
void INSTALL_PREFIX_UNSUPPORTED(Json::Value const* value, cmJSONState* state)
162
0
{
163
0
  state->AddErrorAtValue(
164
0
    "File version must be 3 or higher for installDir preset "
165
0
    "support",
166
0
    value);
167
0
}
168
169
void CONDITION_UNSUPPORTED(cmJSONState* state)
170
0
{
171
0
  state->AddError("File version must be 3 or higher for condition support");
172
0
}
173
174
void TOOLCHAIN_FILE_UNSUPPORTED(cmJSONState* state)
175
0
{
176
0
  state->AddError("File version must be 3 or higher for toolchainFile preset "
177
0
                  "support");
178
0
}
179
180
void GRAPHVIZ_FILE_UNSUPPORTED(cmJSONState* state)
181
0
{
182
0
  state->AddError(
183
0
    "File version must be 10 or higher for graphviz preset support");
184
0
}
185
186
void JOBS_PROC_UNSUPPORTED(cmJSONState* state)
187
0
{
188
0
  state->AddError("File version must be 11 or higher for "
189
0
                  "processor-count-based jobs preset support");
190
0
}
191
192
void CYCLIC_INCLUDE(std::string const& file, cmJSONState* state)
193
0
{
194
0
  state->AddError(cmStrCat("Cyclic include among preset files: ", file));
195
0
}
196
197
void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state)
198
0
{
199
0
  state->AddError("File version must be 5 or higher for testOutputTruncation "
200
0
                  "preset support");
201
0
}
202
203
void INVALID_WORKFLOW_STEPS(std::string const& workflowStep,
204
                            cmJSONState* state)
205
0
{
206
0
  state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, '"'));
207
0
}
208
209
void NO_WORKFLOW_STEPS(std::string const& presetName, cmJSONState* state)
210
0
{
211
0
  state->AddError(
212
0
    cmStrCat("No workflow steps specified for \"", presetName, '"'));
213
0
}
214
215
void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(std::string const& stepName,
216
                                       cmJSONState* state)
217
0
{
218
0
  state->AddError(cmStrCat("First workflow step \"", stepName,
219
0
                           "\" must be a configure step"));
220
0
}
221
222
void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(std::string const& stepName,
223
                                       cmJSONState* state)
224
0
{
225
0
  state->AddError(cmStrCat("Configure workflow step \"", stepName,
226
0
                           "\" must be the first step"));
227
0
}
228
229
void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(std::string const& workflowStep,
230
                                         cmJSONState* state)
231
0
{
232
0
  state->AddError(cmStrCat("Workflow step \"", workflowStep,
233
0
                           "\" is unreachable from preset's file"));
234
0
}
235
236
void CTEST_JUNIT_UNSUPPORTED(cmJSONState* state)
237
0
{
238
0
  state->AddError(
239
0
    "File version must be 6 or higher for CTest JUnit output support");
240
0
}
241
242
void TRACE_UNSUPPORTED(cmJSONState* state)
243
0
{
244
0
  state->AddError("File version must be 7 or higher for trace preset support");
245
0
}
246
247
JsonErrors::ErrorGenerator UNRECOGNIZED_VERSION_RANGE(int min, int max)
248
4
{
249
4
  return [min, max](Json::Value const* value, cmJSONState* state) -> void {
250
0
    state->AddErrorAtValue(cmStrCat("Unrecognized \"version\" ",
251
0
                                    value->asString(), ": must be >=", min,
252
0
                                    " and <=", max),
253
0
                           value);
254
0
  };
255
4
}
256
257
JsonErrors::ErrorGenerator UNRECOGNIZED_CMAKE_VERSION(
258
  std::string const& version, int current, int required)
259
0
{
260
0
  return [version, current, required](Json::Value const* value,
261
0
                                      cmJSONState* state) -> void {
262
0
    state->AddErrorAtValue(cmStrCat("\"cmakeMinimumRequired\" ", version,
263
0
                                    " version ", required,
264
0
                                    " must be less than ", current),
265
0
                           value);
266
0
  };
267
0
}
268
269
void INVALID_PRESET_NAME(Json::Value const* value, cmJSONState* state)
270
0
{
271
0
  std::string errMsg = "Invalid Preset Name";
272
0
  if (value && value->isConvertibleTo(Json::ValueType::stringValue) &&
273
0
      !value->asString().empty()) {
274
0
    errMsg = cmStrCat(errMsg, ": ", value->asString());
275
0
  }
276
0
  state->AddErrorAtValue(errMsg, value);
277
0
}
278
279
void INVALID_CONDITION(Json::Value const* value, cmJSONState* state)
280
0
{
281
0
  state->AddErrorAtValue(
282
0
    cmStrCat("Invalid condition for preset \"", getPresetName(state), '"'),
283
0
    value);
284
0
}
285
286
JsonErrors::ErrorGenerator INVALID_CONDITION_OBJECT(
287
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
288
0
{
289
0
  return JsonErrors::INVALID_NAMED_OBJECT(
290
0
    [](Json::Value const*, cmJSONState* state) -> std::string {
291
0
      return cmStrCat(" condition for preset \"", getPresetName(state), '"');
292
0
    })(errorType, extraFields);
293
0
}
294
295
JsonErrors::ErrorGenerator INVALID_VARIABLE_OBJECT(
296
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
297
0
{
298
0
  return JsonErrors::INVALID_NAMED_OBJECT(
299
0
    [](Json::Value const*, cmJSONState* state) -> std::string {
300
0
      return getVariableName(state);
301
0
    })(errorType, extraFields);
302
0
}
303
304
JsonErrors::ErrorGenerator INVALID_PRESET_OBJECT(
305
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
306
0
{
307
0
  return JsonErrors::INVALID_NAMED_OBJECT(
308
0
    [](Json::Value const*, cmJSONState*) -> std::string { return "Preset"; })(
309
0
    errorType, extraFields);
310
0
}
311
312
JsonErrors::ErrorGenerator INVALID_ROOT_OBJECT(
313
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
314
0
{
315
0
  return JsonErrors::INVALID_NAMED_OBJECT(
316
0
    [](Json::Value const*, cmJSONState*) -> std::string {
317
0
      return "root object";
318
0
    })(errorType, extraFields);
319
0
}
320
321
void PRESET_MISSING_FIELD(std::string const& presetName,
322
                          std::string const& missingField, cmJSONState* state)
323
0
{
324
0
  state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
325
0
                           missingField, '"'));
326
0
}
327
328
void SCHEMA_UNSUPPORTED(cmJSONState* state)
329
0
{
330
0
  state->AddError("File version must be 8 or higher for $schema support");
331
0
}
332
}