Coverage Report

Created: 2026-06-15 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCMakePresetsGraph.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 "cmCMakePresetsGraph.h"
4
5
#include <algorithm>
6
#include <cassert>
7
#include <functional>
8
#include <iomanip>
9
#include <iostream>
10
#include <iterator>
11
#include <utility>
12
13
#include <cm/memory>
14
15
#include "cmsys/RegularExpression.hxx"
16
17
#include "cmCMakePresetsErrors.h"
18
#include "cmCMakePresetsGraphInternal.h"
19
#include "cmStringAlgorithms.h"
20
#include "cmSystemTools.h"
21
22
#define CHECK_EXPAND(out, field, expanders, version)                          \
23
0
  do {                                                                        \
24
0
    switch (ExpandMacros(field, expanders, version)) {                        \
25
0
      case ExpandMacroResult::Error:                                          \
26
0
        return false;                                                         \
27
0
      case ExpandMacroResult::Ignore:                                         \
28
0
        out.reset();                                                          \
29
0
        return true;                                                          \
30
0
      case ExpandMacroResult::Defer:                                          \
31
0
        CM_FALLTHROUGH;                                                       \
32
0
      case ExpandMacroResult::Ok:                                             \
33
0
        break;                                                                \
34
0
    }                                                                         \
35
0
  } while (false)
36
37
namespace {
38
enum class CycleStatus
39
{
40
  Unvisited,
41
  InProgress,
42
  Verified,
43
};
44
45
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
46
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
47
using TestPreset = cmCMakePresetsGraph::TestPreset;
48
using PackagePreset = cmCMakePresetsGraph::PackagePreset;
49
using WorkflowPreset = cmCMakePresetsGraph::WorkflowPreset;
50
template <typename T>
51
using PresetPair = cmCMakePresetsGraph::PresetPair<T>;
52
using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
53
using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
54
using MacroExpanderVector = cmCMakePresetsGraphInternal::MacroExpanderVector;
55
using BaseMacroExpander = cmCMakePresetsGraphInternal::BaseMacroExpander;
56
template <typename T>
57
using PresetMacroExpander =
58
  cmCMakePresetsGraphInternal::PresetMacroExpander<T>;
59
template <typename T>
60
using ImmediateMacroExpander =
61
  cmCMakePresetsGraphInternal::ImmediateMacroExpander<T>;
62
using cmCMakePresetsGraphInternal::ExpandMacros;
63
64
bool gSkipNewLine = true;
65
66
void InheritString(std::string& child, std::string const& parent)
67
0
{
68
0
  if (child.empty()) {
69
0
    child = parent;
70
0
  }
71
0
}
72
73
template <typename T>
74
void InheritOptionalValue(cm::optional<T>& child,
75
                          cm::optional<T> const& parent)
76
0
{
77
0
  if (!child) {
78
0
    child = parent;
79
0
  }
80
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<bool>(std::__1::optional<bool>&, std::__1::optional<bool> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCMakePresetsGraph::TraceEnableMode>(std::__1::optional<cmCMakePresetsGraph::TraceEnableMode>&, std::__1::optional<cmCMakePresetsGraph::TraceEnableMode> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmTraceEnums::TraceOutputFormat>(std::__1::optional<cmTraceEnums::TraceOutputFormat>&, std::__1::optional<cmTraceEnums::TraceOutputFormat> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<unsigned int>(std::__1::optional<unsigned int>&, std::__1::optional<unsigned int> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum>(std::__1::optional<cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum>&, std::__1::optional<cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<int>(std::__1::optional<int>&, std::__1::optional<int> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCTestTypes::TruncationMode>(std::__1::optional<cmCTestTypes::TruncationMode>&, std::__1::optional<cmCTestTypes::TruncationMode> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCMakePresetsGraph::TestPreset::IncludeOptions::IndexOptions>(std::__1::optional<cmCMakePresetsGraph::TestPreset::IncludeOptions::IndexOptions>&, std::__1::optional<cmCMakePresetsGraph::TestPreset::IncludeOptions::IndexOptions> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCMakePresetsGraph::TestPreset::ExcludeOptions::FixturesOptions>(std::__1::optional<cmCMakePresetsGraph::TestPreset::ExcludeOptions::FixturesOptions>&, std::__1::optional<cmCMakePresetsGraph::TestPreset::ExcludeOptions::FixturesOptions> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<std::__1::optional<unsigned int> >(std::__1::optional<std::__1::optional<unsigned int> >&, std::__1::optional<std::__1::optional<unsigned int> > const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCMakePresetsGraph::TestPreset::ExecutionOptions::ShowOnlyEnum>(std::__1::optional<cmCMakePresetsGraph::TestPreset::ExecutionOptions::ShowOnlyEnum>&, std::__1::optional<cmCMakePresetsGraph::TestPreset::ExecutionOptions::ShowOnlyEnum> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions>(std::__1::optional<cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions>&, std::__1::optional<cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions> const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritOptionalValue<cmCMakePresetsGraph::TestPreset::ExecutionOptions::NoTestsActionEnum>(std::__1::optional<cmCMakePresetsGraph::TestPreset::ExecutionOptions::NoTestsActionEnum>&, std::__1::optional<cmCMakePresetsGraph::TestPreset::ExecutionOptions::NoTestsActionEnum> const&)
81
82
template <typename T>
83
void InheritVector(std::vector<T>& child, std::vector<T> const& parent)
84
0
{
85
0
  if (child.empty()) {
86
0
    child = parent;
87
0
  }
88
0
}
89
90
template <typename K, typename V>
91
void InheritMap(std::map<K, V>& child, std::map<K, V> const& parent)
92
0
{
93
0
  for (auto const& item : parent) {
94
0
    child.insert(item);
95
0
  }
96
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritMap<cmDiagnostics::DiagnosticCategory, bool>(std::__1::map<cmDiagnostics::DiagnosticCategory, bool, std::__1::less<cmDiagnostics::DiagnosticCategory>, std::__1::allocator<std::__1::pair<cmDiagnostics::DiagnosticCategory const, bool> > >&, std::__1::map<cmDiagnostics::DiagnosticCategory, bool, std::__1::less<cmDiagnostics::DiagnosticCategory>, std::__1::allocator<std::__1::pair<cmDiagnostics::DiagnosticCategory const, bool> > > const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritMap<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::optional<cmCMakePresetsGraph::CacheVariable> >(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::optional<cmCMakePresetsGraph::CacheVariable>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::optional<cmCMakePresetsGraph::CacheVariable> > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::optional<cmCMakePresetsGraph::CacheVariable>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::optional<cmCMakePresetsGraph::CacheVariable> > > > const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritMap<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > > const&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::InheritMap<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > > > const&)
97
98
/**
99
 * Check preset inheritance for cycles (using a DAG check algorithm) while
100
 * also bubbling up fields through the inheritance hierarchy, then verify
101
 * that each preset has the required fields, either directly or through
102
 * inheritance.
103
 */
104
template <typename T>
105
bool VisitPreset(
106
  T& preset,
107
  std::map<std::string, cmCMakePresetsGraph::PresetPair<T>>& presets,
108
  std::map<std::string, CycleStatus> cycleStatus, cmCMakePresetsGraph& graph)
109
0
{
110
0
  switch (cycleStatus[preset.Name]) {
111
0
    case CycleStatus::InProgress:
112
0
      cmCMakePresetsErrors::CYCLIC_PRESET_INHERITANCE(
113
0
        preset.Name, preset.kind(), &graph.parseState);
114
0
      return false;
115
0
    case CycleStatus::Verified:
116
0
      return true;
117
0
    default:
118
0
      break;
119
0
  }
120
121
0
  cycleStatus[preset.Name] = CycleStatus::InProgress;
122
123
0
  if (preset.Environment.count("") != 0) {
124
0
    cmCMakePresetsErrors::INVALID_PRESET_NAMED(
125
0
      preset.Name, preset.kind(), &graph.parseState,
126
0
      "Empty environment variable names are not allowed");
127
0
    return false;
128
0
  }
129
130
0
  bool result = preset.VisitPresetBeforeInherit();
131
0
  if (!result) {
132
0
    cmCMakePresetsErrors::INVALID_PRESET_NAMED(
133
0
      preset.Name, preset.kind(), &graph.parseState, preset.ErrorDetail);
134
0
    return false;
135
0
  }
136
137
0
  for (auto const& i : preset.Inherits) {
138
0
    auto parent = presets.find(i);
139
0
    if (parent == presets.end()) {
140
0
      cmCMakePresetsErrors::INVALID_PRESET_NAMED(
141
0
        preset.Name, preset.kind(), &graph.parseState,
142
0
        cmStrCat("Could not find inherited preset \"", i, "\""));
143
0
      return false;
144
0
    }
145
146
0
    auto& parentPreset = parent->second.Unexpanded;
147
0
    if (!preset.OriginFile->ReachableFiles.count(parentPreset.OriginFile)) {
148
0
      cmCMakePresetsErrors::INHERITED_PRESET_UNREACHABLE_FROM_FILE(
149
0
        preset.Name, preset.kind(), &graph.parseState);
150
0
      return false;
151
0
    }
152
153
0
    if (!VisitPreset(parentPreset, presets, cycleStatus, graph)) {
154
0
      return false;
155
0
    }
156
157
0
    result = preset.VisitPresetInherit(parentPreset);
158
0
    if (!result) {
159
0
      cmCMakePresetsErrors::INVALID_PRESET_NAMED(
160
0
        preset.Name, preset.kind(), &graph.parseState, preset.ErrorDetail);
161
0
      return false;
162
0
    }
163
164
0
    InheritMap(preset.Environment, parentPreset.Environment);
165
166
0
    if (!preset.ConditionEvaluator) {
167
0
      preset.ConditionEvaluator = parentPreset.ConditionEvaluator;
168
0
    }
169
0
  }
170
171
0
  if (preset.ConditionEvaluator && preset.ConditionEvaluator->IsNull()) {
172
0
    preset.ConditionEvaluator.reset();
173
0
  }
174
175
0
  result = preset.VisitPresetAfterInherit(graph.GetVersion(preset),
176
0
                                          &graph.parseState);
177
0
  if (!result) {
178
0
    cmCMakePresetsErrors::INVALID_PRESET_NAMED(
179
0
      preset.Name, preset.kind(), &graph.parseState, preset.ErrorDetail);
180
0
    return false;
181
0
  }
182
183
0
  cycleStatus[preset.Name] = CycleStatus::Verified;
184
0
  return true;
185
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::VisitPreset<cmCMakePresetsGraph::ConfigurePreset>(cmCMakePresetsGraph::ConfigurePreset&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset> > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::VisitPreset<cmCMakePresetsGraph::BuildPreset>(cmCMakePresetsGraph::BuildPreset&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset> > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::VisitPreset<cmCMakePresetsGraph::TestPreset>(cmCMakePresetsGraph::TestPreset&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset> > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::VisitPreset<cmCMakePresetsGraph::PackagePreset>(cmCMakePresetsGraph::PackagePreset&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset> > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::VisitPreset<cmCMakePresetsGraph::WorkflowPreset>(cmCMakePresetsGraph::WorkflowPreset&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::WorkflowPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::WorkflowPreset> > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >, cmCMakePresetsGraph&)
186
187
template <typename T>
188
bool ComputePresetInheritance(
189
  std::map<std::string, cmCMakePresetsGraph::PresetPair<T>>& presets,
190
  cmCMakePresetsGraph& graph)
191
0
{
192
0
  std::map<std::string, CycleStatus> cycleStatus;
193
0
  for (auto const& it : presets) {
194
0
    cycleStatus[it.first] = CycleStatus::Unvisited;
195
0
  }
196
197
0
  for (auto& it : presets) {
198
0
    auto& preset = it.second.Unexpanded;
199
0
    if (!VisitPreset<T>(preset, presets, cycleStatus, graph)) {
200
0
      return false;
201
0
    }
202
0
  }
203
204
0
  return true;
205
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ComputePresetInheritance<cmCMakePresetsGraph::ConfigurePreset>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset> > > >&, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ComputePresetInheritance<cmCMakePresetsGraph::BuildPreset>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset> > > >&, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ComputePresetInheritance<cmCMakePresetsGraph::TestPreset>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset> > > >&, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ComputePresetInheritance<cmCMakePresetsGraph::PackagePreset>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset> > > >&, cmCMakePresetsGraph&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ComputePresetInheritance<cmCMakePresetsGraph::WorkflowPreset>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::WorkflowPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::WorkflowPreset> > > >&, cmCMakePresetsGraph&)
206
207
constexpr char const* ValidPrefixes[] = {
208
  "",
209
  "env",
210
  "penv",
211
  "vendor",
212
};
213
214
bool PrefixesValidMacroNamespace(std::string const& str)
215
0
{
216
0
  return std::any_of(
217
0
    std::begin(ValidPrefixes), std::end(ValidPrefixes),
218
0
    [&str](char const* prefix) -> bool { return cmHasPrefix(prefix, str); });
219
0
}
220
221
bool IsValidMacroNamespace(std::string const& str)
222
0
{
223
0
  return std::any_of(
224
0
    std::begin(ValidPrefixes), std::end(ValidPrefixes),
225
0
    [&str](char const* prefix) -> bool { return str == prefix; });
226
0
}
227
228
ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status,
229
                           MacroExpanderVector const& macroExpanders,
230
                           int version);
231
template <typename T>
232
class EnvironmentMacroExpander : public MacroExpander
233
{
234
  std::map<std::string, CycleStatus>& EnvCycles;
235
  cm::optional<T>& Out;
236
  MacroExpanderVector& MacroExpanders;
237
238
public:
239
  EnvironmentMacroExpander(MacroExpanderVector& macroExpanders,
240
                           cm::optional<T>& out,
241
                           std::map<std::string, CycleStatus>& envCycles)
242
0
    : EnvCycles(envCycles)
243
0
    , Out(out)
244
0
    , MacroExpanders(macroExpanders)
245
0
  {
246
0
  }
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::ConfigurePreset>::EnvironmentMacroExpander(std::__1::vector<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> >, std::__1::allocator<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> > > >&, std::__1::optional<cmCMakePresetsGraph::ConfigurePreset>&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::BuildPreset>::EnvironmentMacroExpander(std::__1::vector<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> >, std::__1::allocator<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> > > >&, std::__1::optional<cmCMakePresetsGraph::BuildPreset>&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::TestPreset>::EnvironmentMacroExpander(std::__1::vector<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> >, std::__1::allocator<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> > > >&, std::__1::optional<cmCMakePresetsGraph::TestPreset>&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::PackagePreset>::EnvironmentMacroExpander(std::__1::vector<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> >, std::__1::allocator<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> > > >&, std::__1::optional<cmCMakePresetsGraph::PackagePreset>&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::WorkflowPreset>::EnvironmentMacroExpander(std::__1::vector<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> >, std::__1::allocator<std::__1::unique_ptr<cmCMakePresetsGraphInternal::MacroExpander, std::__1::default_delete<cmCMakePresetsGraphInternal::MacroExpander> > > >&, std::__1::optional<cmCMakePresetsGraph::WorkflowPreset>&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::CycleStatus, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, (anonymous namespace)::CycleStatus> > >&)
247
  ExpandMacroResult operator()(std::string const& macroNamespace,
248
                               std::string const& macroName,
249
                               std::string& macroOut,
250
                               int version) const override
251
0
  {
252
0
    if (macroNamespace == "env" && !macroName.empty() && Out) {
253
0
      auto v = Out->Environment.find(macroName);
254
0
      if (v != Out->Environment.end() && v->second) {
255
0
        auto e =
256
0
          VisitEnv(*v->second, EnvCycles[macroName], MacroExpanders, version);
257
0
        if (e != ExpandMacroResult::Ok) {
258
0
          return e;
259
0
        }
260
0
        macroOut += *v->second;
261
0
        return ExpandMacroResult::Ok;
262
0
      }
263
0
    }
264
265
0
    if (macroNamespace == "env" || macroNamespace == "penv") {
266
0
      if (macroName.empty()) {
267
0
        return ExpandMacroResult::Error;
268
0
      }
269
0
      if (cm::optional<std::string> value =
270
0
            cmSystemTools::GetEnvVar(macroName)) {
271
0
        macroOut += *value;
272
0
      }
273
0
      return ExpandMacroResult::Ok;
274
0
    }
275
276
0
    return ExpandMacroResult::Ignore;
277
0
  }
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::ConfigurePreset>::operator()(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::BuildPreset>::operator()(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::TestPreset>::operator()(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::PackagePreset>::operator()(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:(anonymous namespace)::EnvironmentMacroExpander<cmCMakePresetsGraph::WorkflowPreset>::operator()(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int) const
278
};
279
280
bool CheckExpandMacros(ConfigurePreset const& preset,
281
                       cm::optional<ConfigurePreset>& out,
282
                       MacroExpanderVector const& macroExpanders,
283
                       cmCMakePresetsGraph const* graph = nullptr)
284
0
{
285
0
  int version = graph ? graph->GetVersion(preset) : preset.OriginFile->Version;
286
287
0
  std::string binaryDir = preset.BinaryDir;
288
0
  CHECK_EXPAND(out, binaryDir, macroExpanders, version);
289
290
0
  if (!binaryDir.empty()) {
291
0
    if (graph) {
292
0
      if (!cmSystemTools::FileIsFullPath(binaryDir)) {
293
0
        binaryDir = cmStrCat(graph->SourceDir, '/', binaryDir);
294
0
      }
295
0
      out->BinaryDir = cmSystemTools::CollapseFullPath(binaryDir);
296
0
      cmSystemTools::ConvertToUnixSlashes(out->BinaryDir);
297
0
    } else {
298
      // Defer path normalization until the graph is merged, but store the
299
      // intermediate result.
300
0
      out->BinaryDir = binaryDir;
301
0
    }
302
0
  }
303
304
0
  if (!preset.InstallDir.empty()) {
305
0
    std::string installDir = preset.InstallDir;
306
0
    CHECK_EXPAND(out, installDir, macroExpanders, version);
307
308
0
    if (graph) {
309
0
      if (!cmSystemTools::FileIsFullPath(installDir)) {
310
0
        installDir = cmStrCat(graph->SourceDir, '/', installDir);
311
0
      }
312
0
      out->InstallDir = cmSystemTools::CollapseFullPath(installDir);
313
0
      cmSystemTools::ConvertToUnixSlashes(out->InstallDir);
314
0
    } else {
315
      // Defer path normalization until the graph is merged, but store the
316
      // intermediate result.
317
0
      out->InstallDir = installDir;
318
0
    }
319
0
  }
320
321
0
  if (!preset.ToolchainFile.empty()) {
322
0
    std::string toolchain = preset.ToolchainFile;
323
0
    CHECK_EXPAND(out, toolchain, macroExpanders, version);
324
0
    out->ToolchainFile = toolchain;
325
0
  }
326
327
0
  if (!preset.GraphVizFile.empty()) {
328
0
    std::string graphVizFile = preset.GraphVizFile;
329
0
    CHECK_EXPAND(out, graphVizFile, macroExpanders, version);
330
0
    out->GraphVizFile = graphVizFile;
331
0
  }
332
333
0
  for (auto& variable : out->CacheVariables) {
334
0
    if (variable.second) {
335
0
      CHECK_EXPAND(out, variable.second->Value, macroExpanders, version);
336
0
    }
337
0
  }
338
339
0
  return true;
340
0
}
341
342
bool CheckExpandMacros(BuildPreset const& preset,
343
                       cm::optional<BuildPreset>& out,
344
                       MacroExpanderVector const& macroExpanders,
345
                       cmCMakePresetsGraph const* graph = nullptr)
346
0
{
347
0
  int version = graph ? graph->GetVersion(preset) : preset.OriginFile->Version;
348
349
0
  for (auto& target : out->Targets) {
350
0
    CHECK_EXPAND(out, target, macroExpanders, version);
351
0
  }
352
353
0
  for (auto& nativeToolOption : out->NativeToolOptions) {
354
0
    CHECK_EXPAND(out, nativeToolOption, macroExpanders, version);
355
0
  }
356
357
0
  return true;
358
0
}
359
360
bool CheckExpandMacros(TestPreset const& preset, cm::optional<TestPreset>& out,
361
                       MacroExpanderVector const& macroExpanders,
362
                       cmCMakePresetsGraph const* graph = nullptr)
363
0
{
364
0
  int version = graph ? graph->GetVersion(preset) : preset.OriginFile->Version;
365
366
0
  for (auto& overwrite : out->OverwriteConfigurationFile) {
367
0
    CHECK_EXPAND(out, overwrite, macroExpanders, version);
368
0
  }
369
370
0
  if (out->Output) {
371
0
    CHECK_EXPAND(out, out->Output->OutputLogFile, macroExpanders, version);
372
0
    CHECK_EXPAND(out, out->Output->OutputJUnitFile, macroExpanders, version);
373
0
  }
374
375
0
  if (out->Filter) {
376
0
    if (out->Filter->Include) {
377
0
      CHECK_EXPAND(out, out->Filter->Include->Name, macroExpanders, version);
378
0
      CHECK_EXPAND(out, out->Filter->Include->Label, macroExpanders, version);
379
380
0
      if (out->Filter->Include->Index) {
381
0
        CHECK_EXPAND(out, out->Filter->Include->Index->IndexFile,
382
0
                     macroExpanders, version);
383
0
      }
384
0
    }
385
386
0
    if (out->Filter->Exclude) {
387
0
      CHECK_EXPAND(out, out->Filter->Exclude->Name, macroExpanders, version);
388
0
      CHECK_EXPAND(out, out->Filter->Exclude->Label, macroExpanders, version);
389
390
0
      if (out->Filter->Exclude->Fixtures) {
391
0
        CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Any, macroExpanders,
392
0
                     version);
393
0
        CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Setup,
394
0
                     macroExpanders, version);
395
0
        CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Cleanup,
396
0
                     macroExpanders, version);
397
0
      }
398
0
    }
399
0
  }
400
401
0
  if (out->Execution) {
402
0
    CHECK_EXPAND(out, out->Execution->ResourceSpecFile, macroExpanders,
403
0
                 version);
404
0
  }
405
406
0
  return true;
407
0
}
408
409
bool CheckExpandMacros(PackagePreset const& preset,
410
                       cm::optional<PackagePreset>& out,
411
                       MacroExpanderVector const& macroExpanders,
412
                       cmCMakePresetsGraph const* graph = nullptr)
413
0
{
414
0
  int version = graph ? graph->GetVersion(preset) : preset.OriginFile->Version;
415
416
0
  for (auto& variable : out->Variables) {
417
0
    CHECK_EXPAND(out, variable.second, macroExpanders, version);
418
0
  }
419
420
0
  CHECK_EXPAND(out, out->ConfigFile, macroExpanders, version);
421
0
  CHECK_EXPAND(out, out->PackageName, macroExpanders, version);
422
0
  CHECK_EXPAND(out, out->PackageVersion, macroExpanders, version);
423
0
  CHECK_EXPAND(out, out->PackageDirectory, macroExpanders, version);
424
0
  CHECK_EXPAND(out, out->VendorName, macroExpanders, version);
425
426
0
  return true;
427
0
}
428
429
bool CheckExpandMacros(WorkflowPreset const& /*preset*/,
430
                       cm::optional<WorkflowPreset>& /*out*/,
431
                       MacroExpanderVector const& /*macroExpanders*/,
432
                       cmCMakePresetsGraph const* /*graph*/ = nullptr)
433
0
{
434
0
  return true;
435
0
}
436
437
template <typename T>
438
bool ExpandMacros(cmCMakePresetsGraph* graph, T const& preset,
439
                  cm::optional<T>& out)
440
0
{
441
0
  out.emplace(preset);
442
443
0
  std::map<std::string, CycleStatus> envCycles;
444
0
  for (auto const& v : out->Environment) {
445
0
    envCycles[v.first] = CycleStatus::Unvisited;
446
0
  }
447
448
0
  MacroExpanderVector macroExpanders{};
449
450
0
  macroExpanders.push_back(cm::make_unique<BaseMacroExpander>(*graph));
451
0
  macroExpanders.push_back(
452
0
    cm::make_unique<PresetMacroExpander<T>>(*graph, preset));
453
0
  macroExpanders.push_back(cm::make_unique<EnvironmentMacroExpander<T>>(
454
0
    macroExpanders, out, envCycles));
455
456
0
  for (auto& v : out->Environment) {
457
0
    if (v.second) {
458
0
      switch (VisitEnv(*v.second, envCycles[v.first], macroExpanders,
459
0
                       graph->GetVersion(preset))) {
460
0
        case ExpandMacroResult::Error:
461
0
          cmCMakePresetsErrors::INVALID_PRESET_NAMED(
462
0
            preset.Name, preset.kind(), &graph->parseState,
463
0
            "Invalid macro expansion");
464
0
          return false;
465
0
        case ExpandMacroResult::Ignore:
466
0
          out.reset();
467
0
          return true;
468
0
        case ExpandMacroResult::Defer:
469
0
          CM_FALLTHROUGH;
470
0
        case ExpandMacroResult::Ok:
471
0
          break;
472
0
      }
473
0
    }
474
0
  }
475
476
0
  if (preset.ConditionEvaluator) {
477
0
    cm::optional<bool> result;
478
0
    if (!preset.ConditionEvaluator->Evaluate(
479
0
          macroExpanders, graph->GetVersion(preset), result)) {
480
0
      cmCMakePresetsErrors::INVALID_PRESET_NAMED(
481
0
        preset.Name, preset.kind(), &graph->parseState, "Invalid condition");
482
0
      return false;
483
0
    }
484
0
    if (!result) {
485
0
      out.reset();
486
0
      return true;
487
0
    }
488
0
    out->ConditionResult = *result;
489
0
  }
490
491
0
  return CheckExpandMacros(preset, out, macroExpanders, graph);
492
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ExpandMacros<cmCMakePresetsGraph::ConfigurePreset>(cmCMakePresetsGraph*, cmCMakePresetsGraph::ConfigurePreset const&, std::__1::optional<cmCMakePresetsGraph::ConfigurePreset>&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ExpandMacros<cmCMakePresetsGraph::BuildPreset>(cmCMakePresetsGraph*, cmCMakePresetsGraph::BuildPreset const&, std::__1::optional<cmCMakePresetsGraph::BuildPreset>&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ExpandMacros<cmCMakePresetsGraph::TestPreset>(cmCMakePresetsGraph*, cmCMakePresetsGraph::TestPreset const&, std::__1::optional<cmCMakePresetsGraph::TestPreset>&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ExpandMacros<cmCMakePresetsGraph::PackagePreset>(cmCMakePresetsGraph*, cmCMakePresetsGraph::PackagePreset const&, std::__1::optional<cmCMakePresetsGraph::PackagePreset>&)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::ExpandMacros<cmCMakePresetsGraph::WorkflowPreset>(cmCMakePresetsGraph*, cmCMakePresetsGraph::WorkflowPreset const&, std::__1::optional<cmCMakePresetsGraph::WorkflowPreset>&)
493
494
ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status,
495
                           MacroExpanderVector const& macroExpanders,
496
                           int version)
497
0
{
498
0
  if (status == CycleStatus::Verified) {
499
0
    return ExpandMacroResult::Ok;
500
0
  }
501
0
  if (status == CycleStatus::InProgress) {
502
0
    return ExpandMacroResult::Error;
503
0
  }
504
505
0
  status = CycleStatus::InProgress;
506
0
  auto e = ExpandMacros(value, macroExpanders, version);
507
0
  if (e != ExpandMacroResult::Ok) {
508
0
    return e;
509
0
  }
510
0
  status = CycleStatus::Verified;
511
0
  return ExpandMacroResult::Ok;
512
0
}
513
514
void PrintPresets(
515
  std::vector<cmCMakePresetsGraph::Preset const*> const& presets)
516
0
{
517
0
  if (presets.empty()) {
518
0
    return;
519
0
  }
520
521
0
  auto presetWithLongestName =
522
0
    std::max_element(presets.begin(), presets.end(),
523
0
                     [](cmCMakePresetsGraph::Preset const* a,
524
0
                        cmCMakePresetsGraph::Preset const* b) {
525
0
                       return a->Name.length() < b->Name.length();
526
0
                     });
527
0
  auto longestLength = (*presetWithLongestName)->Name.length();
528
529
0
  for (auto const* preset : presets) {
530
0
    std::string name = cmStrCat("  \"", preset->Name, '"');
531
0
    if (!preset->DisplayName.empty()) {
532
0
      int const width = static_cast<int>(longestLength + name.length() -
533
0
                                         preset->Name.length());
534
0
      std::cout << std::left << std::setw(width) << name << " - "
535
0
                << preset->DisplayName << '\n';
536
0
    } else {
537
0
      std::cout << name << '\n';
538
0
    }
539
0
  }
540
0
}
541
542
struct AlwaysTrue
543
{
544
  template <typename T>
545
  constexpr bool operator()(T const&) const noexcept
546
0
  {
547
0
    return true;
548
0
  }
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::AlwaysTrue::operator()<cmCMakePresetsGraph::ConfigurePreset>(cmCMakePresetsGraph::ConfigurePreset const&) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::AlwaysTrue::operator()<cmCMakePresetsGraph::BuildPreset>(cmCMakePresetsGraph::BuildPreset const&) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::AlwaysTrue::operator()<cmCMakePresetsGraph::TestPreset>(cmCMakePresetsGraph::TestPreset const&) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::AlwaysTrue::operator()<cmCMakePresetsGraph::PackagePreset>(cmCMakePresetsGraph::PackagePreset const&) const
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::AlwaysTrue::operator()<cmCMakePresetsGraph::WorkflowPreset>(cmCMakePresetsGraph::WorkflowPreset const&) const
549
};
550
551
template <typename PresetType, typename Filter = AlwaysTrue>
552
void PrintPresetList(
553
  cmCMakePresetsGraph const* const graph,
554
  std::map<std::string, cmCMakePresetsGraph::PresetPair<PresetType>>
555
    cmCMakePresetsGraph::*data,
556
  std::vector<std::string> cmCMakePresetsGraph::*index, Filter filter = {})
557
0
{
558
0
  std::vector<cmCMakePresetsGraph::Preset const*> presets;
559
0
  presets.reserve((graph->*index).size());
560
0
  for (auto const& p : graph->*index) {
561
0
    auto const& preset = (graph->*data).at(p);
562
0
    if (!preset.Unexpanded.Hidden && preset.Expanded &&
563
0
        preset.Expanded->ConditionResult && filter(preset.Unexpanded)) {
564
0
      presets.push_back(
565
0
        static_cast<cmCMakePresetsGraph::Preset const*>(&preset.Unexpanded));
566
0
    }
567
0
  }
568
569
0
  if (!presets.empty()) {
570
0
    std::cout << (gSkipNewLine ? "" : "\n") << "Available "
571
0
              << PresetType::kind() << " presets:\n\n";
572
0
    gSkipNewLine = false;
573
0
    PrintPresets(presets);
574
0
  }
575
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::PrintPresetList<cmCMakePresetsGraph::ConfigurePreset, (anonymous namespace)::AlwaysTrue>(cmCMakePresetsGraph const*, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset> > > > cmCMakePresetsGraph::*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > cmCMakePresetsGraph::*, (anonymous namespace)::AlwaysTrue)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::PrintPresetList<cmCMakePresetsGraph::ConfigurePreset, std::__1::function<bool (cmCMakePresetsGraph::ConfigurePreset const&)> >(cmCMakePresetsGraph const*, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset> > > > cmCMakePresetsGraph::*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > cmCMakePresetsGraph::*, std::__1::function<bool (cmCMakePresetsGraph::ConfigurePreset const&)>)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::PrintPresetList<cmCMakePresetsGraph::BuildPreset, (anonymous namespace)::AlwaysTrue>(cmCMakePresetsGraph const*, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset> > > > cmCMakePresetsGraph::*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > cmCMakePresetsGraph::*, (anonymous namespace)::AlwaysTrue)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::PrintPresetList<cmCMakePresetsGraph::TestPreset, (anonymous namespace)::AlwaysTrue>(cmCMakePresetsGraph const*, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset> > > > cmCMakePresetsGraph::*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > cmCMakePresetsGraph::*, (anonymous namespace)::AlwaysTrue)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::PrintPresetList<cmCMakePresetsGraph::PackagePreset, (anonymous namespace)::AlwaysTrue>(cmCMakePresetsGraph const*, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset> > > > cmCMakePresetsGraph::*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > cmCMakePresetsGraph::*, (anonymous namespace)::AlwaysTrue)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::PrintPresetList<cmCMakePresetsGraph::PackagePreset, std::__1::function<bool (cmCMakePresetsGraph::PackagePreset const&)> >(cmCMakePresetsGraph const*, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset> > > > cmCMakePresetsGraph::*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > cmCMakePresetsGraph::*, std::__1::function<bool (cmCMakePresetsGraph::PackagePreset const&)>)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:void (anonymous namespace)::PrintPresetList<cmCMakePresetsGraph::WorkflowPreset, (anonymous namespace)::AlwaysTrue>(cmCMakePresetsGraph const*, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::WorkflowPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::WorkflowPreset> > > > cmCMakePresetsGraph::*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > cmCMakePresetsGraph::*, (anonymous namespace)::AlwaysTrue)
576
}
577
578
template <typename T>
579
bool cmCMakePresetsGraphInternal::ExpandImmediateMacros(T& preset)
580
0
{
581
0
  MacroExpanderVector macroExpanders{};
582
0
  macroExpanders.push_back(cm::make_unique<ImmediateMacroExpander<T>>(preset));
583
0
  cm::optional<T> out = preset;
584
0
  bool result = CheckExpandMacros(preset, out, macroExpanders);
585
0
  if (out.has_value()) {
586
0
    preset = out.value();
587
0
  };
588
0
  return result;
589
0
}
Unexecuted instantiation: bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<cmCMakePresetsGraph::ConfigurePreset>(cmCMakePresetsGraph::ConfigurePreset&)
Unexecuted instantiation: bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<cmCMakePresetsGraph::BuildPreset>(cmCMakePresetsGraph::BuildPreset&)
Unexecuted instantiation: bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<cmCMakePresetsGraph::TestPreset>(cmCMakePresetsGraph::TestPreset&)
Unexecuted instantiation: bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<cmCMakePresetsGraph::PackagePreset>(cmCMakePresetsGraph::PackagePreset&)
Unexecuted instantiation: bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<cmCMakePresetsGraph::WorkflowPreset>(cmCMakePresetsGraph::WorkflowPreset&)
590
591
template bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<
592
  ConfigurePreset>(ConfigurePreset&);
593
template bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<BuildPreset>(
594
  BuildPreset&);
595
template bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<TestPreset>(
596
  TestPreset&);
597
template bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<
598
  PackagePreset>(PackagePreset&);
599
template bool cmCMakePresetsGraphInternal::ExpandImmediateMacros<
600
  WorkflowPreset>(WorkflowPreset&);
601
602
ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacros(
603
  std::string& out, MacroExpanderVector const& macroExpanders, int version)
604
0
{
605
0
  std::string result;
606
0
  std::string macroNamespace;
607
0
  std::string macroName;
608
609
0
  enum class State
610
0
  {
611
0
    Default,
612
0
    MacroNamespace,
613
0
    MacroName,
614
0
  } state = State::Default;
615
616
0
  for (auto c : out) {
617
0
    switch (state) {
618
0
      case State::Default:
619
0
        if (c == '$') {
620
0
          state = State::MacroNamespace;
621
0
        } else {
622
0
          result += c;
623
0
        }
624
0
        break;
625
626
0
      case State::MacroNamespace:
627
0
        if (c == '{') {
628
0
          if (IsValidMacroNamespace(macroNamespace)) {
629
0
            state = State::MacroName;
630
0
          } else {
631
0
            result += '$';
632
0
            result += macroNamespace;
633
0
            result += '{';
634
0
            macroNamespace.clear();
635
0
            state = State::Default;
636
0
          }
637
0
        } else {
638
0
          macroNamespace += c;
639
0
          if (!PrefixesValidMacroNamespace(macroNamespace)) {
640
0
            result += '$';
641
0
            result += macroNamespace;
642
0
            macroNamespace.clear();
643
0
            state = State::Default;
644
0
          }
645
0
        }
646
0
        break;
647
648
0
      case State::MacroName:
649
0
        if (c == '}') {
650
0
          auto e = ExpandMacro(result, macroNamespace, macroName,
651
0
                               macroExpanders, version);
652
0
          if (e != ExpandMacroResult::Ok) {
653
0
            return e;
654
0
          }
655
0
          macroNamespace.clear();
656
0
          macroName.clear();
657
0
          state = State::Default;
658
0
        } else {
659
0
          macroName += c;
660
0
        }
661
0
        break;
662
0
    }
663
0
  }
664
665
0
  switch (state) {
666
0
    case State::Default:
667
0
      break;
668
0
    case State::MacroNamespace:
669
0
      result += '$';
670
0
      result += macroNamespace;
671
0
      break;
672
0
    case State::MacroName:
673
0
      return ExpandMacroResult::Error;
674
0
  }
675
676
0
  out = std::move(result);
677
0
  return ExpandMacroResult::Ok;
678
0
}
679
680
ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacro(
681
  std::string& out, std::string const& macroNamespace,
682
  std::string const& macroName, MacroExpanderVector const& macroExpanders,
683
  int version)
684
0
{
685
0
  for (auto const& macroExpander : macroExpanders) {
686
0
    auto result = (*macroExpander)(macroNamespace, macroName, out, version);
687
0
    if (result != ExpandMacroResult::Ignore) {
688
0
      return result;
689
0
    }
690
0
  }
691
692
0
  if (macroNamespace == "vendor") {
693
0
    return ExpandMacroResult::Ignore;
694
0
  }
695
696
0
  return ExpandMacroResult::Error;
697
0
}
698
699
namespace {
700
template <typename T>
701
bool SetupWorkflowConfigurePreset(T const& preset,
702
                                  ConfigurePreset const*& configurePreset,
703
                                  cmJSONState* state)
704
0
{
705
0
  if (preset.ConfigurePreset != configurePreset->Name) {
706
0
    cmCMakePresetsErrors::INVALID_WORKFLOW_STEPS(configurePreset->Name, state);
707
0
    return false;
708
0
  }
709
0
  return true;
710
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::SetupWorkflowConfigurePreset<cmCMakePresetsGraph::BuildPreset>(cmCMakePresetsGraph::BuildPreset const&, cmCMakePresetsGraph::ConfigurePreset const*&, cmJSONState*)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::SetupWorkflowConfigurePreset<cmCMakePresetsGraph::TestPreset>(cmCMakePresetsGraph::TestPreset const&, cmCMakePresetsGraph::ConfigurePreset const*&, cmJSONState*)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::SetupWorkflowConfigurePreset<cmCMakePresetsGraph::PackagePreset>(cmCMakePresetsGraph::PackagePreset const&, cmCMakePresetsGraph::ConfigurePreset const*&, cmJSONState*)
711
712
template <>
713
bool SetupWorkflowConfigurePreset<ConfigurePreset>(
714
  ConfigurePreset const& preset, ConfigurePreset const*& configurePreset,
715
  cmJSONState*)
716
0
{
717
0
  configurePreset = &preset;
718
0
  return true;
719
0
}
720
721
template <typename T>
722
bool TryReachPresetFromWorkflow(
723
  WorkflowPreset const& origin,
724
  std::map<std::string, PresetPair<T>> const& presets, std::string const& name,
725
  ConfigurePreset const*& configurePreset, cmJSONState* state)
726
0
{
727
0
  auto it = presets.find(name);
728
0
  if (it == presets.end()) {
729
0
    cmCMakePresetsErrors::INVALID_WORKFLOW_STEPS(name, state);
730
0
    return false;
731
0
  }
732
0
  if (!origin.OriginFile->ReachableFiles.count(
733
0
        it->second.Unexpanded.OriginFile)) {
734
0
    cmCMakePresetsErrors::WORKFLOW_STEP_UNREACHABLE_FROM_FILE(name, state);
735
0
    return false;
736
0
  }
737
0
  return SetupWorkflowConfigurePreset<T>(it->second.Unexpanded,
738
0
                                         configurePreset, state);
739
0
}
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::TryReachPresetFromWorkflow<cmCMakePresetsGraph::ConfigurePreset>(cmCMakePresetsGraph::WorkflowPreset const&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::ConfigurePreset> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmCMakePresetsGraph::ConfigurePreset const*&, cmJSONState*)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::TryReachPresetFromWorkflow<cmCMakePresetsGraph::BuildPreset>(cmCMakePresetsGraph::WorkflowPreset const&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmCMakePresetsGraph::ConfigurePreset const*&, cmJSONState*)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::TryReachPresetFromWorkflow<cmCMakePresetsGraph::TestPreset>(cmCMakePresetsGraph::WorkflowPreset const&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmCMakePresetsGraph::ConfigurePreset const*&, cmJSONState*)
Unexecuted instantiation: cmCMakePresetsGraph.cxx:bool (anonymous namespace)::TryReachPresetFromWorkflow<cmCMakePresetsGraph::PackagePreset>(cmCMakePresetsGraph::WorkflowPreset const&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::PackagePreset> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmCMakePresetsGraph::ConfigurePreset const*&, cmJSONState*)
740
}
741
742
ExpandMacroResult BaseMacroExpander::operator()(
743
  std::string const& macroNamespace, std::string const& macroName,
744
  std::string& macroOut, int version) const
745
0
{
746
0
  if (macroNamespace.empty()) {
747
0
    if (macroName == "sourceDir") {
748
0
      macroOut += Graph.SourceDir;
749
0
      return ExpandMacroResult::Ok;
750
0
    }
751
0
    if (macroName == "sourceParentDir") {
752
0
      macroOut += cmSystemTools::GetParentDirectory(Graph.SourceDir);
753
0
      return ExpandMacroResult::Ok;
754
0
    }
755
0
    if (macroName == "sourceDirName") {
756
0
      macroOut += cmSystemTools::GetFilenameName(Graph.SourceDir);
757
0
      return ExpandMacroResult::Ok;
758
0
    }
759
0
    if (macroName == "dollar") {
760
0
      macroOut += '$';
761
0
      return ExpandMacroResult::Ok;
762
0
    }
763
0
    if (macroName == "hostSystemName") {
764
0
      if (version < 3) {
765
0
        return ExpandMacroResult::Error;
766
0
      }
767
0
      macroOut += cmSystemTools::GetSystemName();
768
0
      return ExpandMacroResult::Ok;
769
0
    }
770
    // Enable fileDir macro expansion for non-preset expanders
771
0
    if (macroName == "fileDir" && File) {
772
0
      if (version < 4) {
773
0
        return ExpandMacroResult::Error;
774
0
      }
775
0
      macroOut += cmSystemTools::GetParentDirectory(File.value());
776
0
      return ExpandMacroResult::Ok;
777
0
    }
778
0
    if (macroName == "pathListSep") {
779
0
      if (version < 5) {
780
0
        return ExpandMacroResult::Error;
781
0
      }
782
0
      macroOut += cmSystemTools::GetSystemPathlistSeparator();
783
0
      return ExpandMacroResult::Ok;
784
0
    }
785
0
  }
786
787
0
  return ExpandMacroResult::Ignore;
788
0
}
789
790
bool cmCMakePresetsGraphInternal::EqualsCondition::Evaluate(
791
  MacroExpanderVector const& expanders, int version,
792
  cm::optional<bool>& out) const
793
0
{
794
0
  std::string lhs = this->Lhs;
795
0
  CHECK_EXPAND(out, lhs, expanders, version);
796
797
0
  std::string rhs = this->Rhs;
798
0
  CHECK_EXPAND(out, rhs, expanders, version);
799
800
0
  out = (lhs == rhs);
801
0
  return true;
802
0
}
803
804
bool cmCMakePresetsGraphInternal::InListCondition::Evaluate(
805
  MacroExpanderVector const& expanders, int version,
806
  cm::optional<bool>& out) const
807
0
{
808
0
  std::string str = this->String;
809
0
  CHECK_EXPAND(out, str, expanders, version);
810
811
0
  for (auto item : this->List) {
812
0
    CHECK_EXPAND(out, item, expanders, version);
813
0
    if (str == item) {
814
0
      out = true;
815
0
      return true;
816
0
    }
817
0
  }
818
819
0
  out = false;
820
0
  return true;
821
0
}
822
823
bool cmCMakePresetsGraphInternal::MatchesCondition::Evaluate(
824
  MacroExpanderVector const& expanders, int version,
825
  cm::optional<bool>& out) const
826
0
{
827
0
  std::string str = this->String;
828
0
  CHECK_EXPAND(out, str, expanders, version);
829
0
  std::string regexStr = this->Regex;
830
0
  CHECK_EXPAND(out, regexStr, expanders, version);
831
832
0
  cmsys::RegularExpression regex;
833
0
  if (!regex.compile(regexStr)) {
834
0
    return false;
835
0
  }
836
837
0
  out = regex.find(str);
838
0
  return true;
839
0
}
840
841
bool cmCMakePresetsGraphInternal::AnyAllOfCondition::Evaluate(
842
  MacroExpanderVector const& expanders, int version,
843
  cm::optional<bool>& out) const
844
0
{
845
0
  for (auto const& condition : this->Conditions) {
846
0
    cm::optional<bool> result;
847
0
    if (!condition->Evaluate(expanders, version, result)) {
848
0
      out.reset();
849
0
      return false;
850
0
    }
851
852
0
    if (!result) {
853
0
      out.reset();
854
0
      return true;
855
0
    }
856
857
0
    if (result == this->StopValue) {
858
0
      out = result;
859
0
      return true;
860
0
    }
861
0
  }
862
863
0
  out = !this->StopValue;
864
0
  return true;
865
0
}
866
867
bool cmCMakePresetsGraphInternal::NotCondition::Evaluate(
868
  MacroExpanderVector const& expanders, int version,
869
  cm::optional<bool>& out) const
870
0
{
871
0
  out.reset();
872
0
  if (!this->SubCondition->Evaluate(expanders, version, out)) {
873
0
    out.reset();
874
0
    return false;
875
0
  }
876
0
  if (out) {
877
0
    *out = !*out;
878
0
  }
879
0
  return true;
880
0
}
881
882
bool cmCMakePresetsGraph::ConfigurePreset::VisitPresetInherit(
883
  cmCMakePresetsGraph::Preset const& parentPreset)
884
0
{
885
0
  auto& preset = *this;
886
0
  ConfigurePreset const& parent =
887
0
    static_cast<ConfigurePreset const&>(parentPreset);
888
0
  InheritString(preset.Generator, parent.Generator);
889
0
  InheritString(preset.Architecture, parent.Architecture);
890
0
  InheritString(preset.Toolset, parent.Toolset);
891
0
  if (!preset.ArchitectureStrategy) {
892
0
    preset.ArchitectureStrategy = parent.ArchitectureStrategy;
893
0
  }
894
0
  if (!preset.ToolsetStrategy) {
895
0
    preset.ToolsetStrategy = parent.ToolsetStrategy;
896
0
  }
897
0
  InheritString(preset.BinaryDir, parent.BinaryDir);
898
0
  InheritString(preset.InstallDir, parent.InstallDir);
899
0
  InheritString(preset.ToolchainFile, parent.ToolchainFile);
900
0
  InheritString(preset.GraphVizFile, parent.GraphVizFile);
901
0
  InheritMap(preset.Warnings, parent.Warnings);
902
0
  InheritMap(preset.Errors, parent.Errors);
903
0
  InheritOptionalValue(preset.WarnSystemVars, parent.WarnSystemVars);
904
0
  InheritMap(preset.CacheVariables, parent.CacheVariables);
905
0
  InheritOptionalValue(preset.DebugOutput, parent.DebugOutput);
906
0
  InheritOptionalValue(preset.DebugTryCompile, parent.DebugTryCompile);
907
0
  InheritOptionalValue(preset.DebugFind, parent.DebugFind);
908
0
  InheritOptionalValue(preset.TraceMode, parent.TraceMode);
909
0
  InheritOptionalValue(preset.TraceFormat, parent.TraceFormat);
910
0
  InheritVector(preset.TraceSource, parent.TraceSource);
911
0
  InheritString(preset.TraceRedirect, parent.TraceRedirect);
912
913
0
  return true;
914
0
}
915
916
bool cmCMakePresetsGraph::ConfigurePreset::VisitPresetBeforeInherit()
917
0
{
918
0
  auto& preset = *this;
919
0
  if (preset.Environment.count("") != 0) {
920
0
    this->ErrorDetail =
921
0
      "Empty environment variable names are not allowed in configure presets";
922
0
    return false;
923
0
  }
924
925
0
  return true;
926
0
}
927
928
bool cmCMakePresetsGraph::ConfigurePreset::VisitPresetAfterInherit(
929
  int version, cmJSONState* state)
930
0
{
931
0
  auto& preset = *this;
932
0
  if (!preset.Hidden) {
933
0
    if (version < 3) {
934
0
      if (preset.Generator.empty()) {
935
0
        cmCMakePresetsErrors::PRESET_MISSING_FIELD(preset.Name, "generator",
936
0
                                                   state);
937
0
        return false;
938
0
      }
939
0
      if (preset.BinaryDir.empty()) {
940
0
        cmCMakePresetsErrors::PRESET_MISSING_FIELD(preset.Name, "binaryDir",
941
0
                                                   state);
942
0
        return false;
943
0
      }
944
0
    }
945
946
0
    for (auto const& w : preset.Warnings) {
947
0
      auto const ei = preset.Errors.find(w.first);
948
0
      if (ei != preset.Errors.end()) {
949
0
        if (w.second == false && ei->second == true) {
950
0
          return false;
951
0
        }
952
0
      }
953
0
    }
954
955
0
    if (preset.CacheVariables.count("") != 0) {
956
0
      this->ErrorDetail = "Empty cache variable names are not allowed";
957
0
      return false;
958
0
    }
959
0
  }
960
961
0
  return true;
962
0
}
963
964
bool cmCMakePresetsGraph::BuildPreset::VisitPresetInherit(
965
  cmCMakePresetsGraph::Preset const& parentPreset)
966
0
{
967
0
  auto& preset = *this;
968
0
  BuildPreset const& parent = static_cast<BuildPreset const&>(parentPreset);
969
970
0
  InheritString(preset.ConfigurePreset, parent.ConfigurePreset);
971
0
  InheritOptionalValue(preset.InheritConfigureEnvironment,
972
0
                       parent.InheritConfigureEnvironment);
973
0
  InheritOptionalValue(preset.Jobs, parent.Jobs);
974
0
  InheritVector(preset.Targets, parent.Targets);
975
0
  InheritString(preset.Configuration, parent.Configuration);
976
0
  InheritOptionalValue(preset.CleanFirst, parent.CleanFirst);
977
0
  InheritOptionalValue(preset.Verbose, parent.Verbose);
978
0
  InheritVector(preset.NativeToolOptions, parent.NativeToolOptions);
979
0
  if (!preset.ResolvePackageReferences) {
980
0
    preset.ResolvePackageReferences = parent.ResolvePackageReferences;
981
0
  }
982
983
0
  return true;
984
0
}
985
986
bool cmCMakePresetsGraph::BuildPreset::VisitPresetAfterInherit(
987
  int /* version */, cmJSONState* /*stat*/)
988
0
{
989
0
  if (!this->Hidden && this->ConfigurePreset.empty()) {
990
0
    this->ErrorDetail = "Build presets must either be hidden or have an "
991
0
                        "associated configure preset";
992
0
    return false;
993
0
  }
994
0
  return true;
995
0
}
996
997
bool cmCMakePresetsGraph::TestPreset::VisitPresetInherit(
998
  cmCMakePresetsGraph::Preset const& parentPreset)
999
0
{
1000
0
  auto& preset = *this;
1001
0
  TestPreset const& parent = static_cast<TestPreset const&>(parentPreset);
1002
1003
0
  InheritString(preset.ConfigurePreset, parent.ConfigurePreset);
1004
0
  InheritOptionalValue(preset.InheritConfigureEnvironment,
1005
0
                       parent.InheritConfigureEnvironment);
1006
0
  InheritString(preset.Configuration, parent.Configuration);
1007
0
  InheritVector(preset.OverwriteConfigurationFile,
1008
0
                parent.OverwriteConfigurationFile);
1009
1010
0
  if (parent.Output) {
1011
0
    if (preset.Output) {
1012
0
      auto& output = preset.Output.value();
1013
0
      auto const& parentOutput = parent.Output.value();
1014
0
      InheritOptionalValue(output.ShortProgress, parentOutput.ShortProgress);
1015
0
      InheritOptionalValue(output.Verbosity, parentOutput.Verbosity);
1016
0
      InheritOptionalValue(output.Debug, parentOutput.Debug);
1017
0
      InheritOptionalValue(output.OutputOnFailure,
1018
0
                           parentOutput.OutputOnFailure);
1019
0
      InheritOptionalValue(output.Quiet, parentOutput.Quiet);
1020
0
      InheritString(output.OutputLogFile, parentOutput.OutputLogFile);
1021
0
      InheritString(output.OutputJUnitFile, parentOutput.OutputJUnitFile);
1022
0
      InheritOptionalValue(output.LabelSummary, parentOutput.LabelSummary);
1023
0
      InheritOptionalValue(output.SubprojectSummary,
1024
0
                           parentOutput.SubprojectSummary);
1025
0
      InheritOptionalValue(output.MaxPassedTestOutputSize,
1026
0
                           parentOutput.MaxPassedTestOutputSize);
1027
0
      InheritOptionalValue(output.MaxFailedTestOutputSize,
1028
0
                           parentOutput.MaxFailedTestOutputSize);
1029
0
      InheritOptionalValue(output.TestOutputTruncation,
1030
0
                           parentOutput.TestOutputTruncation);
1031
0
      InheritOptionalValue(output.MaxTestNameWidth,
1032
0
                           parentOutput.MaxTestNameWidth);
1033
0
    } else {
1034
0
      preset.Output = parent.Output;
1035
0
    }
1036
0
  }
1037
1038
0
  if (parent.Filter) {
1039
0
    if (parent.Filter->Include) {
1040
0
      if (preset.Filter && preset.Filter->Include) {
1041
0
        auto& include = *preset.Filter->Include;
1042
0
        auto const& parentInclude = *parent.Filter->Include;
1043
0
        InheritString(include.Name, parentInclude.Name);
1044
0
        InheritString(include.Label, parentInclude.Label);
1045
0
        InheritOptionalValue(include.Index, parentInclude.Index);
1046
0
      } else {
1047
0
        if (!preset.Filter) {
1048
0
          preset.Filter.emplace();
1049
0
        }
1050
0
        preset.Filter->Include = parent.Filter->Include;
1051
0
      }
1052
0
    }
1053
1054
0
    if (parent.Filter->Exclude) {
1055
0
      if (preset.Filter && preset.Filter->Exclude) {
1056
0
        auto& exclude = *preset.Filter->Exclude;
1057
0
        auto const& parentExclude = *parent.Filter->Exclude;
1058
0
        InheritString(exclude.Name, parentExclude.Name);
1059
0
        InheritString(exclude.Label, parentExclude.Label);
1060
0
        InheritOptionalValue(exclude.Fixtures, parentExclude.Fixtures);
1061
0
      } else {
1062
0
        if (!preset.Filter) {
1063
0
          preset.Filter.emplace();
1064
0
        }
1065
0
        preset.Filter->Exclude = parent.Filter->Exclude;
1066
0
      }
1067
0
    }
1068
0
  }
1069
1070
0
  if (parent.Execution) {
1071
0
    if (preset.Execution) {
1072
0
      auto& execution = *preset.Execution;
1073
0
      auto const& parentExecution = *parent.Execution;
1074
0
      InheritOptionalValue(execution.StopOnFailure,
1075
0
                           parentExecution.StopOnFailure);
1076
0
      InheritOptionalValue(execution.EnableFailover,
1077
0
                           parentExecution.EnableFailover);
1078
0
      InheritOptionalValue(execution.Jobs, parentExecution.Jobs);
1079
0
      InheritString(execution.ResourceSpecFile,
1080
0
                    parentExecution.ResourceSpecFile);
1081
0
      InheritOptionalValue(execution.TestLoad, parentExecution.TestLoad);
1082
0
      InheritOptionalValue(execution.ShowOnly, parentExecution.ShowOnly);
1083
0
      InheritOptionalValue(execution.Repeat, parentExecution.Repeat);
1084
0
      InheritOptionalValue(execution.InteractiveDebugging,
1085
0
                           parentExecution.InteractiveDebugging);
1086
0
      InheritOptionalValue(execution.ScheduleRandom,
1087
0
                           parentExecution.ScheduleRandom);
1088
0
      InheritOptionalValue(execution.Timeout, parentExecution.Timeout);
1089
0
      InheritOptionalValue(execution.NoTestsAction,
1090
0
                           parentExecution.NoTestsAction);
1091
0
      InheritVector(execution.TestPassthroughArguments,
1092
0
                    parentExecution.TestPassthroughArguments);
1093
0
    } else {
1094
0
      preset.Execution = parent.Execution;
1095
0
    }
1096
0
  }
1097
1098
0
  return true;
1099
0
}
1100
1101
bool cmCMakePresetsGraph::TestPreset::VisitPresetAfterInherit(
1102
  int /* version */, cmJSONState* /*state*/)
1103
0
{
1104
0
  if (!this->Hidden && this->ConfigurePreset.empty()) {
1105
0
    this->ErrorDetail = "Test presets must either be hidden or have an "
1106
0
                        "associated configure preset";
1107
0
    return false;
1108
0
  }
1109
0
  return true;
1110
0
}
1111
1112
bool cmCMakePresetsGraph::PackagePreset::VisitPresetInherit(
1113
  cmCMakePresetsGraph::Preset const& parentPreset)
1114
0
{
1115
0
  auto& preset = *this;
1116
0
  PackagePreset const& parent =
1117
0
    static_cast<PackagePreset const&>(parentPreset);
1118
1119
0
  InheritString(preset.ConfigurePreset, parent.ConfigurePreset);
1120
0
  InheritOptionalValue(preset.InheritConfigureEnvironment,
1121
0
                       parent.InheritConfigureEnvironment);
1122
0
  InheritVector(preset.Generators, parent.Generators);
1123
0
  InheritVector(preset.Configurations, parent.Configurations);
1124
0
  InheritMap(preset.Variables, parent.Variables);
1125
0
  InheritOptionalValue(preset.DebugOutput, parent.DebugOutput);
1126
0
  InheritOptionalValue(preset.VerboseOutput, parent.VerboseOutput);
1127
0
  InheritString(preset.PackageName, parent.PackageName);
1128
0
  InheritString(preset.PackageVersion, parent.PackageVersion);
1129
0
  InheritString(preset.PackageDirectory, parent.PackageDirectory);
1130
0
  InheritString(preset.VendorName, parent.VendorName);
1131
1132
0
  return true;
1133
0
}
1134
1135
bool cmCMakePresetsGraph::PackagePreset::VisitPresetAfterInherit(
1136
  int /* version */, cmJSONState* /*state*/)
1137
0
{
1138
0
  if (!this->Hidden && this->ConfigurePreset.empty()) {
1139
0
    this->ErrorDetail = "Package presets must either be hidden or have an "
1140
0
                        "associated configure preset";
1141
0
    return false;
1142
0
  }
1143
0
  return true;
1144
0
}
1145
1146
bool cmCMakePresetsGraph::WorkflowPreset::VisitPresetInherit(
1147
  cmCMakePresetsGraph::Preset const& /*parentPreset*/)
1148
0
{
1149
0
  return true;
1150
0
}
1151
1152
bool cmCMakePresetsGraph::WorkflowPreset::VisitPresetAfterInherit(
1153
  int /* version */, cmJSONState* /*state*/)
1154
0
{
1155
0
  return true;
1156
0
}
1157
1158
std::string cmCMakePresetsGraph::GetFilename(std::string const& sourceDir)
1159
0
{
1160
0
  return cmStrCat(sourceDir, "/CMakePresets.json");
1161
0
}
1162
1163
std::string cmCMakePresetsGraph::GetUserFilename(std::string const& sourceDir)
1164
0
{
1165
0
  return cmStrCat(sourceDir, "/CMakeUserPresets.json");
1166
0
}
1167
1168
bool cmCMakePresetsGraph::ReadProjectPresets(std::string const& sourceDir,
1169
                                             std::string const& presetsFile,
1170
                                             ReadOption readFilesOption)
1171
0
{
1172
0
  this->SourceDir = cmSystemTools::CollapseFullPath(sourceDir);
1173
0
  this->ClearPresets();
1174
1175
0
  if (!this->ReadProjectPresetsInternal(presetsFile, readFilesOption)) {
1176
0
    this->ClearPresets();
1177
0
    return false;
1178
0
  }
1179
1180
0
  return true;
1181
0
}
1182
1183
std::string cmCMakePresetsGraph::GetGeneratorForPreset(
1184
  std::string const& presetName) const
1185
0
{
1186
0
  auto configurePresetName = presetName;
1187
1188
0
  auto buildPresetIterator = this->BuildPresets.find(presetName);
1189
0
  if (buildPresetIterator != this->BuildPresets.end()) {
1190
0
    configurePresetName =
1191
0
      buildPresetIterator->second.Unexpanded.ConfigurePreset;
1192
0
  } else {
1193
0
    auto testPresetIterator = this->TestPresets.find(presetName);
1194
0
    if (testPresetIterator != this->TestPresets.end()) {
1195
0
      configurePresetName =
1196
0
        testPresetIterator->second.Unexpanded.ConfigurePreset;
1197
0
    }
1198
0
  }
1199
1200
0
  auto configurePresetIterator =
1201
0
    this->ConfigurePresets.find(configurePresetName);
1202
0
  if (configurePresetIterator != this->ConfigurePresets.end()) {
1203
0
    return configurePresetIterator->second.Unexpanded.Generator;
1204
0
  }
1205
1206
  // This should only happen if the preset is hidden
1207
  // or (for build or test presets) if ConfigurePreset is invalid.
1208
0
  return {};
1209
0
}
1210
1211
bool cmCMakePresetsGraph::ReadProjectPresetsInternal(
1212
  std::string const& presetsFile, ReadOption readFilesOption)
1213
0
{
1214
0
  bool haveOneFile = false;
1215
1216
0
  File* file;
1217
0
  std::string filename;
1218
0
  std::vector<File*> inProgressFiles;
1219
0
  if (!presetsFile.empty()) {
1220
0
    filename = presetsFile;
1221
0
    if (cmSystemTools::FileExists(filename)) {
1222
0
      if (!this->ReadJSONFile(filename, RootType::Any, ReadReason::Root,
1223
0
                              inProgressFiles, file, this->errors)) {
1224
0
        return false;
1225
0
      }
1226
0
      haveOneFile = true;
1227
0
    }
1228
0
  } else {
1229
0
    filename = GetUserFilename(this->SourceDir);
1230
0
    if (cmSystemTools::FileExists(filename)) {
1231
0
      if (!this->ReadJSONFile(filename, RootType::User, ReadReason::Root,
1232
0
                              inProgressFiles, file, this->errors)) {
1233
0
        return false;
1234
0
      }
1235
0
      haveOneFile = true;
1236
0
    } else {
1237
0
      filename = GetFilename(this->SourceDir);
1238
0
      if (cmSystemTools::FileExists(filename)) {
1239
0
        if (!this->ReadJSONFile(filename, RootType::Project, ReadReason::Root,
1240
0
                                inProgressFiles, file, this->errors)) {
1241
0
          return false;
1242
0
        }
1243
0
        haveOneFile = true;
1244
0
      }
1245
0
    }
1246
0
  }
1247
0
  assert(inProgressFiles.empty());
1248
1249
0
  if (!haveOneFile) {
1250
0
    if (readFilesOption == ReadOption::AllowNoFiles) {
1251
0
      return true;
1252
0
    }
1253
0
    cmCMakePresetsErrors::FILE_NOT_FOUND(filename, &this->parseState);
1254
0
    return false;
1255
0
  }
1256
1257
0
  bool result = ComputePresetInheritance(this->ConfigurePresets, *this) &&
1258
0
    ComputePresetInheritance(this->BuildPresets, *this) &&
1259
0
    ComputePresetInheritance(this->TestPresets, *this) &&
1260
0
    ComputePresetInheritance(this->PackagePresets, *this) &&
1261
0
    ComputePresetInheritance(this->WorkflowPresets, *this);
1262
0
  if (!result) {
1263
0
    return false;
1264
0
  }
1265
1266
0
  for (auto& it : this->ConfigurePresets) {
1267
0
    if (!ExpandMacros(this, it.second.Unexpanded, it.second.Expanded)) {
1268
0
      cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
1269
0
                                                    &this->parseState);
1270
0
      return false;
1271
0
    }
1272
0
  }
1273
1274
0
  for (auto& it : this->BuildPresets) {
1275
0
    if (!it.second.Unexpanded.Hidden) {
1276
0
      auto const configurePreset =
1277
0
        this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
1278
0
      if (configurePreset == this->ConfigurePresets.end()) {
1279
0
        cmCMakePresetsErrors::INVALID_CONFIGURE_PRESET(it.first,
1280
0
                                                       &this->parseState);
1281
0
        return false;
1282
0
      }
1283
0
      if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
1284
0
            configurePreset->second.Unexpanded.OriginFile)) {
1285
0
        cmCMakePresetsErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
1286
0
          it.first, &this->parseState);
1287
0
        return false;
1288
0
      }
1289
1290
0
      if (it.second.Unexpanded.InheritConfigureEnvironment.value_or(true)) {
1291
0
        it.second.Unexpanded.Environment.insert(
1292
0
          configurePreset->second.Unexpanded.Environment.begin(),
1293
0
          configurePreset->second.Unexpanded.Environment.end());
1294
0
      }
1295
0
    }
1296
1297
0
    if (!ExpandMacros(this, it.second.Unexpanded, it.second.Expanded)) {
1298
0
      cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
1299
0
                                                    &this->parseState);
1300
0
      return false;
1301
0
    }
1302
0
  }
1303
1304
0
  for (auto& it : this->TestPresets) {
1305
0
    if (!it.second.Unexpanded.Hidden) {
1306
0
      auto const configurePreset =
1307
0
        this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
1308
0
      if (configurePreset == this->ConfigurePresets.end()) {
1309
0
        cmCMakePresetsErrors::INVALID_CONFIGURE_PRESET(it.first,
1310
0
                                                       &this->parseState);
1311
0
        return false;
1312
0
      }
1313
0
      if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
1314
0
            configurePreset->second.Unexpanded.OriginFile)) {
1315
0
        cmCMakePresetsErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
1316
0
          it.first, &this->parseState);
1317
0
        return false;
1318
0
      }
1319
1320
0
      if (it.second.Unexpanded.InheritConfigureEnvironment.value_or(true)) {
1321
0
        it.second.Unexpanded.Environment.insert(
1322
0
          configurePreset->second.Unexpanded.Environment.begin(),
1323
0
          configurePreset->second.Unexpanded.Environment.end());
1324
0
      }
1325
0
    }
1326
1327
0
    if (!ExpandMacros(this, it.second.Unexpanded, it.second.Expanded)) {
1328
0
      cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
1329
0
                                                    &this->parseState);
1330
0
      return false;
1331
0
    }
1332
0
  }
1333
1334
0
  for (auto& it : this->PackagePresets) {
1335
0
    if (!it.second.Unexpanded.Hidden) {
1336
0
      auto const configurePreset =
1337
0
        this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
1338
0
      if (configurePreset == this->ConfigurePresets.end()) {
1339
0
        cmCMakePresetsErrors::INVALID_CONFIGURE_PRESET(it.first,
1340
0
                                                       &this->parseState);
1341
0
        return false;
1342
0
      }
1343
0
      if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
1344
0
            configurePreset->second.Unexpanded.OriginFile)) {
1345
0
        cmCMakePresetsErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
1346
0
          it.first, &this->parseState);
1347
0
        return false;
1348
0
      }
1349
1350
0
      if (it.second.Unexpanded.InheritConfigureEnvironment.value_or(true)) {
1351
0
        it.second.Unexpanded.Environment.insert(
1352
0
          configurePreset->second.Unexpanded.Environment.begin(),
1353
0
          configurePreset->second.Unexpanded.Environment.end());
1354
0
      }
1355
0
    }
1356
1357
0
    if (!ExpandMacros(this, it.second.Unexpanded, it.second.Expanded)) {
1358
0
      cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
1359
0
                                                    &this->parseState);
1360
0
      return false;
1361
0
    }
1362
0
  }
1363
1364
0
  for (auto& it : this->WorkflowPresets) {
1365
0
    using Type = WorkflowPreset::WorkflowStep::Type;
1366
1367
0
    ConfigurePreset const* configurePreset = nullptr;
1368
0
    for (auto const& step : it.second.Unexpanded.Steps) {
1369
0
      if (!configurePreset && step.PresetType != Type::Configure) {
1370
0
        cmCMakePresetsErrors::FIRST_WORKFLOW_STEP_NOT_CONFIGURE(
1371
0
          step.PresetName, &this->parseState);
1372
0
        return false;
1373
0
      }
1374
0
      if (configurePreset && step.PresetType == Type::Configure) {
1375
0
        cmCMakePresetsErrors::CONFIGURE_WORKFLOW_STEP_NOT_FIRST(
1376
0
          step.PresetName, &this->parseState);
1377
0
        return false;
1378
0
      }
1379
1380
0
      switch (step.PresetType) {
1381
0
        case Type::Configure:
1382
0
          result = TryReachPresetFromWorkflow(
1383
0
            it.second.Unexpanded, this->ConfigurePresets, step.PresetName,
1384
0
            configurePreset, &this->parseState);
1385
0
          break;
1386
0
        case Type::Build:
1387
0
          result = TryReachPresetFromWorkflow(
1388
0
            it.second.Unexpanded, this->BuildPresets, step.PresetName,
1389
0
            configurePreset, &this->parseState);
1390
0
          break;
1391
0
        case Type::Test:
1392
0
          result = TryReachPresetFromWorkflow(
1393
0
            it.second.Unexpanded, this->TestPresets, step.PresetName,
1394
0
            configurePreset, &this->parseState);
1395
0
          break;
1396
0
        case Type::Package:
1397
0
          result = TryReachPresetFromWorkflow(
1398
0
            it.second.Unexpanded, this->PackagePresets, step.PresetName,
1399
0
            configurePreset, &this->parseState);
1400
0
          break;
1401
0
      }
1402
0
      if (!result) {
1403
0
        return false;
1404
0
      }
1405
0
    }
1406
1407
0
    if (!configurePreset) {
1408
0
      cmCMakePresetsErrors::NO_WORKFLOW_STEPS(it.first, &this->parseState);
1409
0
      return false;
1410
0
    }
1411
1412
0
    if (!ExpandMacros(this, it.second.Unexpanded, it.second.Expanded)) {
1413
0
      cmCMakePresetsErrors::INVALID_MACRO_EXPANSION(it.first,
1414
0
                                                    &this->parseState);
1415
0
      return false;
1416
0
    }
1417
0
  }
1418
1419
0
  return true;
1420
0
}
1421
1422
void cmCMakePresetsGraph::ClearPresets()
1423
0
{
1424
0
  this->ConfigurePresets.clear();
1425
0
  this->BuildPresets.clear();
1426
0
  this->TestPresets.clear();
1427
0
  this->PackagePresets.clear();
1428
0
  this->WorkflowPresets.clear();
1429
1430
0
  this->ConfigurePresetOrder.clear();
1431
0
  this->BuildPresetOrder.clear();
1432
0
  this->TestPresetOrder.clear();
1433
0
  this->PackagePresetOrder.clear();
1434
0
  this->WorkflowPresetOrder.clear();
1435
1436
0
  this->Files.clear();
1437
0
}
1438
1439
void cmCMakePresetsGraph::PrintConfigurePresetList() const
1440
0
{
1441
0
  PrintPresetList<ConfigurePreset>(this,
1442
0
                                   &cmCMakePresetsGraph::ConfigurePresets,
1443
0
                                   &cmCMakePresetsGraph::ConfigurePresetOrder);
1444
0
}
1445
1446
void cmCMakePresetsGraph::PrintConfigurePresetList(
1447
  std::function<bool(ConfigurePreset const&)> const& filter) const
1448
0
{
1449
0
  PrintPresetList<ConfigurePreset>(
1450
0
    this, &cmCMakePresetsGraph::ConfigurePresets,
1451
0
    &cmCMakePresetsGraph::ConfigurePresetOrder, filter);
1452
0
}
1453
1454
void cmCMakePresetsGraph::PrintBuildPresetList() const
1455
0
{
1456
0
  PrintPresetList<BuildPreset>(this, &cmCMakePresetsGraph::BuildPresets,
1457
0
                               &cmCMakePresetsGraph::BuildPresetOrder);
1458
0
}
1459
1460
void cmCMakePresetsGraph::PrintTestPresetList() const
1461
0
{
1462
0
  PrintPresetList<TestPreset>(this, &cmCMakePresetsGraph::TestPresets,
1463
0
                              &cmCMakePresetsGraph::TestPresetOrder);
1464
0
}
1465
1466
void cmCMakePresetsGraph::PrintPackagePresetList() const
1467
0
{
1468
0
  PrintPresetList<PackagePreset>(this, &cmCMakePresetsGraph::PackagePresets,
1469
0
                                 &cmCMakePresetsGraph::PackagePresetOrder);
1470
0
}
1471
1472
void cmCMakePresetsGraph::PrintPackagePresetList(
1473
  std::function<bool(PackagePreset const&)> const& filter) const
1474
0
{
1475
0
  PrintPresetList<PackagePreset>(this, &cmCMakePresetsGraph::PackagePresets,
1476
0
                                 &cmCMakePresetsGraph::PackagePresetOrder,
1477
0
                                 filter);
1478
0
}
1479
1480
void cmCMakePresetsGraph::PrintWorkflowPresetList() const
1481
0
{
1482
0
  PrintPresetList<WorkflowPreset>(this, &cmCMakePresetsGraph::WorkflowPresets,
1483
0
                                  &cmCMakePresetsGraph::WorkflowPresetOrder);
1484
0
}
1485
1486
void cmCMakePresetsGraph::PrintAllPresets() const
1487
0
{
1488
0
  this->PrintConfigurePresetList();
1489
0
  this->PrintBuildPresetList();
1490
0
  this->PrintTestPresetList();
1491
0
  this->PrintPackagePresetList();
1492
0
  this->PrintWorkflowPresetList();
1493
0
}