Imported Upstream version 3.24.0
[platform/upstream/cmake.git] / Source / cmCMakePresetsGraphReadJSON.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include <algorithm>
4 #include <functional>
5 #include <map>
6 #include <string>
7 #include <unordered_set>
8 #include <utility>
9 #include <vector>
10
11 #include <cm/memory>
12 #include <cm/optional>
13 #include <cmext/string_view>
14
15 #include <cm3p/json/reader.h>
16 #include <cm3p/json/value.h>
17
18 #include "cmsys/FStream.hxx"
19
20 #include "cmCMakePresetsGraph.h"
21 #include "cmCMakePresetsGraphInternal.h"
22 #include "cmJSONHelpers.h"
23 #include "cmStringAlgorithms.h"
24 #include "cmSystemTools.h"
25 #include "cmVersion.h"
26
27 namespace {
28 using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
29 using CacheVariable = cmCMakePresetsGraph::CacheVariable;
30 using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
31 using BuildPreset = cmCMakePresetsGraph::BuildPreset;
32 using TestPreset = cmCMakePresetsGraph::TestPreset;
33 using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
34 using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
35
36 constexpr int MIN_VERSION = 1;
37 constexpr int MAX_VERSION = 5;
38
39 struct CMakeVersion
40 {
41   unsigned int Major = 0;
42   unsigned int Minor = 0;
43   unsigned int Patch = 0;
44 };
45
46 struct RootPresets
47 {
48   CMakeVersion CMakeMinimumRequired;
49   std::vector<cmCMakePresetsGraph::ConfigurePreset> ConfigurePresets;
50   std::vector<cmCMakePresetsGraph::BuildPreset> BuildPresets;
51   std::vector<cmCMakePresetsGraph::TestPreset> TestPresets;
52   std::vector<std::string> Include;
53 };
54
55 std::unique_ptr<cmCMakePresetsGraphInternal::NotCondition> InvertCondition(
56   std::unique_ptr<cmCMakePresetsGraph::Condition> condition)
57 {
58   auto retval = cm::make_unique<cmCMakePresetsGraphInternal::NotCondition>();
59   retval->SubCondition = std::move(condition);
60   return retval;
61 }
62
63 auto const ConditionStringHelper = JSONHelperBuilder::String(
64   ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
65
66 auto const ConditionBoolHelper = JSONHelperBuilder::Bool(
67   ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
68
69 auto const ConditionStringListHelper = JSONHelperBuilder::Vector<std::string>(
70   ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
71   ConditionStringHelper);
72
73 auto const ConstConditionHelper =
74   JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::ConstCondition>(
75     ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
76     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
77     .Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value,
78           ConditionBoolHelper, true);
79
80 auto const EqualsConditionHelper =
81   JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::EqualsCondition>(
82     ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
83     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
84     .Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs,
85           ConditionStringHelper, true)
86     .Bind("rhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Rhs,
87           ConditionStringHelper, true);
88
89 auto const InListConditionHelper =
90   JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::InListCondition>(
91     ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
92     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
93     .Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String,
94           ConditionStringHelper, true)
95     .Bind("list"_s, &cmCMakePresetsGraphInternal::InListCondition::List,
96           ConditionStringListHelper, true);
97
98 auto const MatchesConditionHelper =
99   JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::MatchesCondition>(
100     ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
101     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
102     .Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String,
103           ConditionStringHelper, true)
104     .Bind("regex"_s, &cmCMakePresetsGraphInternal::MatchesCondition::Regex,
105           ConditionStringHelper, true);
106
107 ReadFileResult SubConditionHelper(
108   std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
109   const Json::Value* value);
110
111 auto const ListConditionVectorHelper =
112   JSONHelperBuilder::Vector<std::unique_ptr<cmCMakePresetsGraph::Condition>>(
113     ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
114     SubConditionHelper);
115 auto const AnyAllOfConditionHelper =
116   JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::AnyAllOfCondition>(
117     ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
118     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
119     .Bind("conditions"_s,
120           &cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions,
121           ListConditionVectorHelper);
122
123 auto const NotConditionHelper =
124   JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::NotCondition>(
125     ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
126     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
127     .Bind("condition"_s,
128           &cmCMakePresetsGraphInternal::NotCondition::SubCondition,
129           SubConditionHelper);
130
131 ReadFileResult ConditionHelper(
132   std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
133   const Json::Value* value)
134 {
135   if (!value) {
136     out.reset();
137     return ReadFileResult::READ_OK;
138   }
139
140   if (value->isBool()) {
141     auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>();
142     c->Value = value->asBool();
143     out = std::move(c);
144     return ReadFileResult::READ_OK;
145   }
146
147   if (value->isNull()) {
148     out = cm::make_unique<cmCMakePresetsGraphInternal::NullCondition>();
149     return ReadFileResult::READ_OK;
150   }
151
152   if (value->isObject()) {
153     if (!value->isMember("type")) {
154       return ReadFileResult::INVALID_CONDITION;
155     }
156
157     if (!(*value)["type"].isString()) {
158       return ReadFileResult::INVALID_CONDITION;
159     }
160     auto type = (*value)["type"].asString();
161
162     if (type == "const") {
163       auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>();
164       CHECK_OK(ConstConditionHelper(*c, value));
165       out = std::move(c);
166       return ReadFileResult::READ_OK;
167     }
168
169     if (type == "equals" || type == "notEquals") {
170       auto c = cm::make_unique<cmCMakePresetsGraphInternal::EqualsCondition>();
171       CHECK_OK(EqualsConditionHelper(*c, value));
172       out = std::move(c);
173       if (type == "notEquals") {
174         out = InvertCondition(std::move(out));
175       }
176       return ReadFileResult::READ_OK;
177     }
178
179     if (type == "inList" || type == "notInList") {
180       auto c = cm::make_unique<cmCMakePresetsGraphInternal::InListCondition>();
181       CHECK_OK(InListConditionHelper(*c, value));
182       out = std::move(c);
183       if (type == "notInList") {
184         out = InvertCondition(std::move(out));
185       }
186       return ReadFileResult::READ_OK;
187     }
188
189     if (type == "matches" || type == "notMatches") {
190       auto c =
191         cm::make_unique<cmCMakePresetsGraphInternal::MatchesCondition>();
192       CHECK_OK(MatchesConditionHelper(*c, value));
193       out = std::move(c);
194       if (type == "notMatches") {
195         out = InvertCondition(std::move(out));
196       }
197       return ReadFileResult::READ_OK;
198     }
199
200     if (type == "anyOf" || type == "allOf") {
201       auto c =
202         cm::make_unique<cmCMakePresetsGraphInternal::AnyAllOfCondition>();
203       c->StopValue = (type == "anyOf");
204       CHECK_OK(AnyAllOfConditionHelper(*c, value));
205       out = std::move(c);
206       return ReadFileResult::READ_OK;
207     }
208
209     if (type == "not") {
210       auto c = cm::make_unique<cmCMakePresetsGraphInternal::NotCondition>();
211       CHECK_OK(NotConditionHelper(*c, value));
212       out = std::move(c);
213       return ReadFileResult::READ_OK;
214     }
215   }
216
217   return ReadFileResult::INVALID_CONDITION;
218 }
219
220 ReadFileResult SubConditionHelper(
221   std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
222   const Json::Value* value)
223 {
224   std::unique_ptr<cmCMakePresetsGraph::Condition> ptr;
225   auto result = ConditionHelper(ptr, value);
226   if (ptr && ptr->IsNull()) {
227     return ReadFileResult::INVALID_CONDITION;
228   }
229   out = std::move(ptr);
230   return result;
231 }
232
233 ReadFileResult EnvironmentHelper(cm::optional<std::string>& out,
234                                  const Json::Value* value)
235 {
236   if (!value || value->isNull()) {
237     out = cm::nullopt;
238     return ReadFileResult::READ_OK;
239   }
240   if (value->isString()) {
241     out = value->asString();
242     return ReadFileResult::READ_OK;
243   }
244   return ReadFileResult::INVALID_PRESET;
245 }
246
247 auto const VersionIntHelper = JSONHelperBuilder::Int(
248   ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
249
250 auto const VersionHelper = JSONHelperBuilder::Required<int>(
251   ReadFileResult::NO_VERSION, VersionIntHelper);
252
253 auto const RootVersionHelper =
254   JSONHelperBuilder::Object<int>(ReadFileResult::READ_OK,
255                                  ReadFileResult::INVALID_ROOT)
256     .Bind("version"_s, VersionHelper, false);
257
258 auto const CMakeVersionUIntHelper = JSONHelperBuilder::UInt(
259   ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
260
261 auto const CMakeVersionHelper =
262   JSONHelperBuilder::Object<CMakeVersion>(
263     ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false)
264     .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false)
265     .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false)
266     .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false);
267
268 auto const IncludeHelper = JSONHelperBuilder::String(
269   ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE);
270
271 auto const IncludeVectorHelper = JSONHelperBuilder::Vector<std::string>(
272   ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper);
273
274 auto const RootPresetsHelper =
275   JSONHelperBuilder::Object<RootPresets>(ReadFileResult::READ_OK,
276                                          ReadFileResult::INVALID_ROOT, false)
277     .Bind<int>("version"_s, nullptr, VersionHelper)
278     .Bind("configurePresets"_s, &RootPresets::ConfigurePresets,
279           cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false)
280     .Bind("buildPresets"_s, &RootPresets::BuildPresets,
281           cmCMakePresetsGraphInternal::BuildPresetsHelper, false)
282     .Bind("testPresets"_s, &RootPresets::TestPresets,
283           cmCMakePresetsGraphInternal::TestPresetsHelper, false)
284     .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired,
285           CMakeVersionHelper, false)
286     .Bind("include"_s, &RootPresets::Include, IncludeVectorHelper, false)
287     .Bind<std::nullptr_t>(
288       "vendor"_s, nullptr,
289       cmCMakePresetsGraphInternal::VendorHelper(ReadFileResult::INVALID_ROOT),
290       false);
291 }
292
293 namespace cmCMakePresetsGraphInternal {
294 cmCMakePresetsGraph::ReadFileResult PresetStringHelper(
295   std::string& out, const Json::Value* value)
296 {
297   static auto const helper = JSONHelperBuilder::String(
298     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
299
300   return helper(out, value);
301 }
302
303 cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper(
304   std::vector<std::string>& out, const Json::Value* value)
305 {
306   static auto const helper = JSONHelperBuilder::Vector<std::string>(
307     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
308     cmCMakePresetsGraphInternal::PresetStringHelper);
309
310   return helper(out, value);
311 }
312
313 cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out,
314                                                      const Json::Value* value)
315 {
316   static auto const helper = JSONHelperBuilder::Bool(
317     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
318
319   return helper(out, value);
320 }
321
322 cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper(
323   cm::optional<bool>& out, const Json::Value* value)
324 {
325   static auto const helper = JSONHelperBuilder::Optional<bool>(
326     ReadFileResult::READ_OK, PresetBoolHelper);
327
328   return helper(out, value);
329 }
330
331 cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out,
332                                                     const Json::Value* value)
333 {
334   static auto const helper = JSONHelperBuilder::Int(
335     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
336
337   return helper(out, value);
338 }
339
340 cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper(
341   cm::optional<int>& out, const Json::Value* value)
342 {
343   static auto const helper =
344     JSONHelperBuilder::Optional<int>(ReadFileResult::READ_OK, PresetIntHelper);
345
346   return helper(out, value);
347 }
348
349 cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper(
350   std::vector<int>& out, const Json::Value* value)
351 {
352   static auto const helper = JSONHelperBuilder::Vector<int>(
353     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper);
354
355   return helper(out, value);
356 }
357
358 cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error)
359 {
360   return [error](std::nullptr_t& /*out*/,
361                  const Json::Value* value) -> ReadFileResult {
362     if (!value) {
363       return ReadFileResult::READ_OK;
364     }
365
366     if (!value->isObject()) {
367       return error;
368     }
369
370     return ReadFileResult::READ_OK;
371   };
372 }
373
374 ReadFileResult PresetConditionHelper(
375   std::shared_ptr<cmCMakePresetsGraph::Condition>& out,
376   const Json::Value* value)
377 {
378   std::unique_ptr<cmCMakePresetsGraph::Condition> ptr;
379   auto result = ConditionHelper(ptr, value);
380   out = std::move(ptr);
381   return result;
382 }
383
384 ReadFileResult PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out,
385                                                  const Json::Value* value)
386 {
387   out.clear();
388   if (!value) {
389     return ReadFileResult::READ_OK;
390   }
391
392   if (value->isString()) {
393     out.push_back(value->asString());
394     return ReadFileResult::READ_OK;
395   }
396
397   return PresetVectorStringHelper(out, value);
398 }
399
400 cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper(
401   std::map<std::string, cm::optional<std::string>>& out,
402   const Json::Value* value)
403 {
404   static auto const helper = JSONHelperBuilder::Map<cm::optional<std::string>>(
405     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
406     EnvironmentHelper);
407
408   return helper(out, value);
409 }
410 }
411
412 cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
413   const std::string& filename, RootType rootType, ReadReason readReason,
414   std::vector<File*>& inProgressFiles, File*& file)
415 {
416   ReadFileResult result;
417
418   for (auto const& f : this->Files) {
419     if (cmSystemTools::SameFile(filename, f->Filename)) {
420       file = f.get();
421       auto fileIt =
422         std::find(inProgressFiles.begin(), inProgressFiles.end(), file);
423       if (fileIt != inProgressFiles.end()) {
424         return cmCMakePresetsGraph::ReadFileResult::CYCLIC_INCLUDE;
425       }
426
427       return cmCMakePresetsGraph::ReadFileResult::READ_OK;
428     }
429   }
430
431   cmsys::ifstream fin(filename.c_str());
432   if (!fin) {
433     return ReadFileResult::FILE_NOT_FOUND;
434   }
435   // If there's a BOM, toss it.
436   cmsys::FStream::ReadBOM(fin);
437
438   Json::Value root;
439   Json::CharReaderBuilder builder;
440   Json::CharReaderBuilder::strictMode(&builder.settings_);
441   if (!Json::parseFromStream(builder, fin, &root, nullptr)) {
442     return ReadFileResult::JSON_PARSE_ERROR;
443   }
444
445   int v = 0;
446   if ((result = RootVersionHelper(v, &root)) != ReadFileResult::READ_OK) {
447     return result;
448   }
449   if (v < MIN_VERSION || v > MAX_VERSION) {
450     return ReadFileResult::UNRECOGNIZED_VERSION;
451   }
452
453   // Support for build and test presets added in version 2.
454   if (v < 2 &&
455       (root.isMember("buildPresets") || root.isMember("testPresets"))) {
456     return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED;
457   }
458
459   // Support for include added in version 4.
460   if (v < 4 && root.isMember("include")) {
461     return ReadFileResult::INCLUDE_UNSUPPORTED;
462   }
463
464   RootPresets presets;
465   if ((result = RootPresetsHelper(presets, &root)) !=
466       ReadFileResult::READ_OK) {
467     return result;
468   }
469
470   unsigned int currentMajor = cmVersion::GetMajorVersion();
471   unsigned int currentMinor = cmVersion::GetMinorVersion();
472   unsigned int currentPatch = cmVersion::GetPatchVersion();
473   auto const& required = presets.CMakeMinimumRequired;
474   if (required.Major > currentMajor ||
475       (required.Major == currentMajor &&
476        (required.Minor > currentMinor ||
477         (required.Minor == currentMinor &&
478          (required.Patch > currentPatch))))) {
479     return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION;
480   }
481
482   auto filePtr = cm::make_unique<File>();
483   file = filePtr.get();
484   this->Files.emplace_back(std::move(filePtr));
485   inProgressFiles.emplace_back(file);
486   file->Filename = filename;
487   file->Version = v;
488   file->ReachableFiles.insert(file);
489
490   for (auto& preset : presets.ConfigurePresets) {
491     preset.OriginFile = file;
492     if (preset.Name.empty()) {
493       return ReadFileResult::INVALID_PRESET;
494     }
495
496     PresetPair<ConfigurePreset> presetPair;
497     presetPair.Unexpanded = preset;
498     presetPair.Expanded = cm::nullopt;
499     if (!this->ConfigurePresets
500            .emplace(std::make_pair(preset.Name, presetPair))
501            .second) {
502       return ReadFileResult::DUPLICATE_PRESETS;
503     }
504
505     // Support for installDir presets added in version 3.
506     if (v < 3 && !preset.InstallDir.empty()) {
507       return ReadFileResult::INSTALL_PREFIX_UNSUPPORTED;
508     }
509
510     // Support for conditions added in version 3.
511     if (v < 3 && preset.ConditionEvaluator) {
512       return ReadFileResult::CONDITION_UNSUPPORTED;
513     }
514
515     // Support for toolchainFile presets added in version 3.
516     if (v < 3 && !preset.ToolchainFile.empty()) {
517       return ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED;
518     }
519
520     this->ConfigurePresetOrder.push_back(preset.Name);
521   }
522
523   for (auto& preset : presets.BuildPresets) {
524     preset.OriginFile = file;
525     if (preset.Name.empty()) {
526       return ReadFileResult::INVALID_PRESET;
527     }
528
529     PresetPair<BuildPreset> presetPair;
530     presetPair.Unexpanded = preset;
531     presetPair.Expanded = cm::nullopt;
532     if (!this->BuildPresets.emplace(preset.Name, presetPair).second) {
533       return ReadFileResult::DUPLICATE_PRESETS;
534     }
535
536     // Support for conditions added in version 3.
537     if (v < 3 && preset.ConditionEvaluator) {
538       return ReadFileResult::CONDITION_UNSUPPORTED;
539     }
540
541     this->BuildPresetOrder.push_back(preset.Name);
542   }
543
544   for (auto& preset : presets.TestPresets) {
545     preset.OriginFile = file;
546     if (preset.Name.empty()) {
547       return ReadFileResult::INVALID_PRESET;
548     }
549
550     PresetPair<TestPreset> presetPair;
551     presetPair.Unexpanded = preset;
552     presetPair.Expanded = cm::nullopt;
553     if (!this->TestPresets.emplace(preset.Name, presetPair).second) {
554       return ReadFileResult::DUPLICATE_PRESETS;
555     }
556
557     // Support for conditions added in version 3.
558     if (v < 3 && preset.ConditionEvaluator) {
559       return ReadFileResult::CONDITION_UNSUPPORTED;
560     }
561
562     // Support for TestOutputTruncation added in version 5.
563     if (v < 5 && preset.Output && preset.Output->TestOutputTruncation) {
564       return ReadFileResult::TEST_OUTPUT_TRUNCATION_UNSUPPORTED;
565     }
566
567     this->TestPresetOrder.push_back(preset.Name);
568   }
569
570   auto const includeFile = [this, &inProgressFiles, file](
571                              const std::string& include, RootType rootType2,
572                              ReadReason readReason2) -> ReadFileResult {
573     ReadFileResult r;
574     File* includedFile;
575     if ((r = this->ReadJSONFile(include, rootType2, readReason2,
576                                 inProgressFiles, includedFile)) !=
577         ReadFileResult::READ_OK) {
578       return r;
579     }
580
581     file->ReachableFiles.insert(includedFile->ReachableFiles.begin(),
582                                 includedFile->ReachableFiles.end());
583     return ReadFileResult::READ_OK;
584   };
585
586   for (auto include : presets.Include) {
587     if (!cmSystemTools::FileIsFullPath(include)) {
588       auto directory = cmSystemTools::GetFilenamePath(filename);
589       include = cmStrCat(directory, '/', include);
590     }
591
592     if ((result = includeFile(include, rootType, ReadReason::Included)) !=
593         ReadFileResult::READ_OK) {
594       return result;
595     }
596   }
597
598   if (rootType == RootType::User && readReason == ReadReason::Root) {
599     auto cmakePresetsFilename = GetFilename(this->SourceDir);
600     if (cmSystemTools::FileExists(cmakePresetsFilename)) {
601       if ((result = includeFile(cmakePresetsFilename, RootType::Project,
602                                 ReadReason::Root)) !=
603           ReadFileResult::READ_OK) {
604         return result;
605       }
606     }
607   }
608
609   inProgressFiles.pop_back();
610   return ReadFileResult::READ_OK;
611 }