Coverage Report

Created: 2026-06-15 07:03

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,
84
                          std::string const& kind, cmJSONState* state,
85
                          std::string const& detail)
86
0
{
87
0
  std::string err_msg =
88
0
    cmStrCat("Invalid ", kind, " preset: \"", presetName, '"');
89
0
  if (!detail.empty()) {
90
0
    err_msg = cmStrCat(err_msg, ": ", detail);
91
0
  }
92
0
  state->AddError(err_msg);
93
0
}
94
95
void INVALID_VARIABLE(Json::Value const* value, cmJSONState* state)
96
0
{
97
0
  std::string var = cmCMakePresetsErrors::getVariableName(state);
98
0
  state->AddErrorAtValue(cmStrCat("Invalid CMake ", var), value);
99
0
}
100
101
void DUPLICATE_PRESETS(std::string const& presetName, cmJSONState* state)
102
0
{
103
0
  state->AddError(cmStrCat("Duplicate preset: \"", presetName, '"'));
104
0
}
105
106
void CYCLIC_PRESET_INHERITANCE(std::string const& presetName,
107
                               std::string const& kind, cmJSONState* state)
108
109
0
{
110
0
  state->AddError(cmStrCat("Cyclic preset inheritance for ", kind,
111
0
                           " preset \"", presetName, '"'));
112
0
}
113
114
void INHERITED_PRESET_UNREACHABLE_FROM_FILE(std::string const& presetName,
115
                                            std::string const& kind,
116
                                            cmJSONState* state)
117
0
{
118
0
  state->AddError(cmStrCat("Inherited ", kind, " preset \"", presetName,
119
0
                           "\" is unreachable from preset's file"));
120
0
}
121
122
void CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(std::string const& presetName,
123
                                            cmJSONState* state)
124
0
{
125
0
  state->AddError(cmStrCat("Configure preset \"", presetName,
126
0
                           "\" is unreachable from preset's file"));
127
0
}
128
129
void INVALID_MACRO_EXPANSION(std::string const& presetName, cmJSONState* state)
130
0
{
131
0
  state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, '"'));
132
0
}
133
134
void BUILD_TEST_PRESETS_UNSUPPORTED(Json::Value const*, cmJSONState* state)
135
0
{
136
0
  state->AddError("File version must be 2 or higher for build and test preset "
137
0
                  "support");
138
0
}
139
140
void PACKAGE_PRESETS_UNSUPPORTED(Json::Value const*, cmJSONState* state)
141
0
{
142
0
  state->AddError(
143
0
    "File version must be 6 or higher for package preset support");
144
0
}
145
146
void WORKFLOW_PRESETS_UNSUPPORTED(Json::Value const*, cmJSONState* state)
147
0
{
148
0
  state->AddError(
149
0
    "File version must be 6 or higher for workflow preset support");
150
0
}
151
152
void INCLUDE_UNSUPPORTED(Json::Value const*, cmJSONState* state)
153
0
{
154
0
  state->AddError("File version must be 4 or higher for include support");
155
0
}
156
157
void INVALID_INCLUDE(Json::Value const* value, cmJSONState* state)
158
0
{
159
0
  state->AddErrorAtValue("Invalid \"include\" field", value);
160
0
}
161
162
void INVALID_CONFIGURE_PRESET(std::string const& presetName,
163
                              cmJSONState* state)
164
0
{
165
0
  state->AddError(
166
0
    cmStrCat(R"(Invalid "configurePreset": ")", presetName, '"'));
167
0
}
168
169
void INSTALL_PREFIX_UNSUPPORTED(Json::Value const* value, cmJSONState* state)
170
0
{
171
0
  state->AddErrorAtValue(
172
0
    "File version must be 3 or higher for installDir preset "
173
0
    "support",
174
0
    value);
175
0
}
176
177
void CONDITION_UNSUPPORTED(cmJSONState* state)
178
0
{
179
0
  state->AddError("File version must be 3 or higher for condition support");
180
0
}
181
182
void TOOLCHAIN_FILE_UNSUPPORTED(cmJSONState* state)
183
0
{
184
0
  state->AddError("File version must be 3 or higher for toolchainFile preset "
185
0
                  "support");
186
0
}
187
188
void GRAPHVIZ_FILE_UNSUPPORTED(cmJSONState* state)
189
0
{
190
0
  state->AddError(
191
0
    "File version must be 10 or higher for graphviz preset support");
192
0
}
193
194
void JOBS_PROC_UNSUPPORTED(cmJSONState* state)
195
0
{
196
0
  state->AddError("File version must be 11 or higher for "
197
0
                  "processor-count-based jobs preset support");
198
0
}
199
200
void PASSTHROUGH_ARGS_UNSUPPORTED(cmJSONState* state)
201
0
{
202
0
  state->AddError("File version must be 12 or higher for "
203
0
                  "testPassthroughArguments preset support");
204
0
}
205
206
void CYCLIC_INCLUDE(std::string const& file, cmJSONState* state)
207
0
{
208
0
  state->AddError(cmStrCat("Cyclic include among presets files: ", file));
209
0
}
210
211
void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state)
212
0
{
213
0
  state->AddError("File version must be 5 or higher for testOutputTruncation "
214
0
                  "preset support");
215
0
}
216
217
void INVALID_WORKFLOW_STEPS(std::string const& workflowStep,
218
                            cmJSONState* state)
219
0
{
220
0
  state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, '"'));
221
0
}
222
223
void NO_WORKFLOW_STEPS(std::string const& presetName, cmJSONState* state)
224
0
{
225
0
  state->AddError(
226
0
    cmStrCat("No workflow steps specified for \"", presetName, '"'));
227
0
}
228
229
void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(std::string const& stepName,
230
                                       cmJSONState* state)
231
0
{
232
0
  state->AddError(cmStrCat("First workflow step \"", stepName,
233
0
                           "\" must be a configure step"));
234
0
}
235
236
void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(std::string const& stepName,
237
                                       cmJSONState* state)
238
0
{
239
0
  state->AddError(cmStrCat("Configure workflow step \"", stepName,
240
0
                           "\" must be the first step"));
241
0
}
242
243
void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(std::string const& workflowStep,
244
                                         cmJSONState* state)
245
0
{
246
0
  state->AddError(cmStrCat("Workflow step \"", workflowStep,
247
0
                           "\" is unreachable from preset's file"));
248
0
}
249
250
void CTEST_JUNIT_UNSUPPORTED(cmJSONState* state)
251
0
{
252
0
  state->AddError(
253
0
    "File version must be 6 or higher for CTest JUnit output support");
254
0
}
255
256
void TRACE_UNSUPPORTED(cmJSONState* state)
257
0
{
258
0
  state->AddError("File version must be 7 or higher for trace preset support");
259
0
}
260
261
JsonErrors::ErrorGenerator UNRECOGNIZED_VERSION_RANGE(int min, int max)
262
4
{
263
4
  return [min, max](Json::Value const* value, cmJSONState* state) -> void {
264
0
    state->AddErrorAtValue(cmStrCat("Unrecognized \"version\" ",
265
0
                                    value->asString(), ": must be >=", min,
266
0
                                    " and <=", max),
267
0
                           value);
268
0
  };
269
4
}
270
271
JsonErrors::ErrorGenerator UNRECOGNIZED_CMAKE_VERSION(
272
  std::string const& version, int current, int required)
273
0
{
274
0
  return [version, current, required](Json::Value const* value,
275
0
                                      cmJSONState* state) -> void {
276
0
    state->AddErrorAtValue(cmStrCat("\"cmakeMinimumRequired\" ", version,
277
0
                                    " version ", required,
278
0
                                    " must be less than ", current),
279
0
                           value);
280
0
  };
281
0
}
282
283
void INVALID_PRESET_NAME(Json::Value const* value, cmJSONState* state)
284
0
{
285
0
  std::string errMsg = "Invalid Preset Name";
286
0
  if (value && value->isConvertibleTo(Json::ValueType::stringValue) &&
287
0
      !value->asString().empty()) {
288
0
    errMsg = cmStrCat(errMsg, ": ", value->asString());
289
0
  }
290
0
  state->AddErrorAtValue(errMsg, value);
291
0
}
292
293
void INVALID_CONDITION(Json::Value const* value, cmJSONState* state)
294
0
{
295
0
  state->AddErrorAtValue(
296
0
    cmStrCat("Invalid condition for preset \"", getPresetName(state), '"'),
297
0
    value);
298
0
}
299
300
JsonErrors::ErrorGenerator INVALID_CONDITION_OBJECT(
301
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
302
0
{
303
0
  return JsonErrors::INVALID_NAMED_OBJECT(
304
0
    [](Json::Value const*, cmJSONState* state) -> std::string {
305
0
      return cmStrCat(" condition for preset \"", getPresetName(state), '"');
306
0
    })(errorType, extraFields);
307
0
}
308
309
JsonErrors::ErrorGenerator INVALID_VARIABLE_OBJECT(
310
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
311
0
{
312
0
  return JsonErrors::INVALID_NAMED_OBJECT(
313
0
    [](Json::Value const*, cmJSONState* state) -> std::string {
314
0
      return getVariableName(state);
315
0
    })(errorType, extraFields);
316
0
}
317
318
JsonErrors::ErrorGenerator INVALID_PRESET_OBJECT(
319
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
320
0
{
321
0
  return JsonErrors::INVALID_NAMED_OBJECT(
322
0
    [](Json::Value const*, cmJSONState*) -> std::string { return "Preset"; })(
323
0
    errorType, extraFields);
324
0
}
325
326
JsonErrors::ErrorGenerator INVALID_ROOT_OBJECT(
327
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
328
0
{
329
0
  return JsonErrors::INVALID_NAMED_OBJECT(
330
0
    [](Json::Value const*, cmJSONState*) -> std::string {
331
0
      return "root object";
332
0
    })(errorType, extraFields);
333
0
}
334
335
void PRESET_MISSING_FIELD(std::string const& presetName,
336
                          std::string const& missingField, cmJSONState* state)
337
0
{
338
0
  state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
339
0
                           missingField, '"'));
340
0
}
341
342
void SCHEMA_UNSUPPORTED(cmJSONState* state)
343
0
{
344
0
  state->AddError("File version must be 8 or higher for $schema support");
345
0
}
346
347
void DIAGNOSTIC_UNSUPPORTED(cm::string_view name, cm::string_view context,
348
                            int version, cmJSONState* state)
349
0
{
350
0
  state->AddError(cmStrCat("File version must be ", std::to_string(version),
351
0
                           " or higher for ", context, '.', name, " support"));
352
0
}
353
354
void DIAGNOSTIC_REMOVED(cm::string_view name, cm::string_view context,
355
                        int version, cmJSONState* state)
356
0
{
357
0
  state->AddError(cmStrCat("File version must be ", std::to_string(version),
358
0
                           " or lower for ", context, '.', name, " support"));
359
0
}
360
}