/src/CMake/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #include <cstddef> |
4 | | #include <functional> |
5 | | #include <map> |
6 | | #include <memory> |
7 | | #include <string> |
8 | | #include <vector> |
9 | | |
10 | | #include <cm/optional> |
11 | | #include <cmext/string_view> |
12 | | |
13 | | #include <cm3p/json/value.h> |
14 | | |
15 | | #include "cmCMakePresetsErrors.h" |
16 | | #include "cmCMakePresetsGraph.h" |
17 | | #include "cmCMakePresetsGraphInternal.h" |
18 | | #include "cmJSONHelpers.h" |
19 | | #include "cmStateTypes.h" |
20 | | |
21 | | class cmJSONState; |
22 | | |
23 | | namespace { |
24 | | using CacheVariable = cmCMakePresetsGraph::CacheVariable; |
25 | | using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; |
26 | | using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; |
27 | | using JSONHelperBuilder = cmJSONHelperBuilder; |
28 | | using TraceEnableMode = cmCMakePresetsGraph::TraceEnableMode; |
29 | | using TraceOutputFormat = cmTraceEnums::TraceOutputFormat; |
30 | | |
31 | | bool ArchToolsetStrategyHelper(cm::optional<ArchToolsetStrategy>& out, |
32 | | Json::Value const* value, cmJSONState* state) |
33 | 0 | { |
34 | 0 | if (!value) { |
35 | 0 | out = cm::nullopt; |
36 | 0 | return true; |
37 | 0 | } |
38 | | |
39 | 0 | if (!value->isString()) { |
40 | 0 | cmCMakePresetsErrors::INVALID_PRESET(value, state); |
41 | 0 | return false; |
42 | 0 | } |
43 | | |
44 | 0 | if (value->asString() == "set") { |
45 | 0 | out = ArchToolsetStrategy::Set; |
46 | 0 | return true; |
47 | 0 | } |
48 | | |
49 | 0 | if (value->asString() == "external") { |
50 | 0 | out = ArchToolsetStrategy::External; |
51 | 0 | return true; |
52 | 0 | } |
53 | | |
54 | 0 | cmCMakePresetsErrors::INVALID_PRESET(value, state); |
55 | 0 | return false; |
56 | 0 | } |
57 | | |
58 | | std::function<bool(ConfigurePreset&, Json::Value const*, cmJSONState*)> |
59 | | ArchToolsetHelper( |
60 | | std::string ConfigurePreset::*valueField, |
61 | | cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField) |
62 | 8 | { |
63 | 8 | auto const objectHelper = |
64 | 8 | JSONHelperBuilder::Object<ConfigurePreset>(JsonErrors::INVALID_OBJECT, |
65 | 8 | false) |
66 | 8 | .Bind("value", valueField, |
67 | 8 | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
68 | 8 | .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); |
69 | 8 | return [valueField, strategyField, |
70 | 8 | objectHelper](ConfigurePreset& out, Json::Value const* value, |
71 | 8 | cmJSONState* state) -> bool { |
72 | 0 | if (!value) { |
73 | 0 | (out.*valueField).clear(); |
74 | 0 | out.*strategyField = cm::nullopt; |
75 | 0 | return true; |
76 | 0 | } |
77 | | |
78 | 0 | if (value->isString()) { |
79 | 0 | out.*valueField = value->asString(); |
80 | 0 | out.*strategyField = cm::nullopt; |
81 | 0 | return true; |
82 | 0 | } |
83 | | |
84 | 0 | if (value->isObject()) { |
85 | 0 | return objectHelper(out, value, state); |
86 | 0 | } |
87 | | |
88 | 0 | cmCMakePresetsErrors::INVALID_PRESET(value, state); |
89 | 0 | return false; |
90 | 0 | }; |
91 | 8 | } |
92 | | |
93 | | auto const ArchitectureHelper = ArchToolsetHelper( |
94 | | &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); |
95 | | auto const ToolsetHelper = ArchToolsetHelper( |
96 | | &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); |
97 | | |
98 | | bool TraceEnableModeHelper(cm::optional<TraceEnableMode>& out, |
99 | | Json::Value const* value, cmJSONState* state) |
100 | 0 | { |
101 | 0 | if (!value) { |
102 | 0 | out = cm::nullopt; |
103 | 0 | return true; |
104 | 0 | } |
105 | | |
106 | 0 | if (!value->isString()) { |
107 | 0 | cmCMakePresetsErrors::INVALID_PRESET(value, state); |
108 | 0 | return false; |
109 | 0 | } |
110 | | |
111 | 0 | if (value->asString() == "on") { |
112 | 0 | out = TraceEnableMode::Default; |
113 | 0 | } else if (value->asString() == "off") { |
114 | 0 | out = TraceEnableMode::Disable; |
115 | 0 | } else if (value->asString() == "expand") { |
116 | 0 | out = TraceEnableMode::Expand; |
117 | 0 | } else { |
118 | 0 | cmCMakePresetsErrors::INVALID_PRESET(value, state); |
119 | 0 | return false; |
120 | 0 | } |
121 | | |
122 | 0 | return true; |
123 | 0 | } |
124 | | |
125 | | bool TraceOutputFormatHelper(cm::optional<TraceOutputFormat>& out, |
126 | | Json::Value const* value, cmJSONState* state) |
127 | 0 | { |
128 | 0 | if (!value) { |
129 | 0 | out = cm::nullopt; |
130 | 0 | return true; |
131 | 0 | } |
132 | | |
133 | 0 | if (!value->isString()) { |
134 | 0 | cmCMakePresetsErrors::INVALID_PRESET(value, state); |
135 | 0 | return false; |
136 | 0 | } |
137 | | |
138 | 0 | if (value->asString() == "human") { |
139 | 0 | out = TraceOutputFormat::Human; |
140 | 0 | } else if (value->asString() == "json-v1") { |
141 | 0 | out = TraceOutputFormat::JSONv1; |
142 | 0 | } else { |
143 | 0 | cmCMakePresetsErrors::INVALID_PRESET(value, state); |
144 | 0 | return false; |
145 | 0 | } |
146 | | |
147 | 0 | return true; |
148 | 0 | } |
149 | | |
150 | | auto const VariableStringHelper = JSONHelperBuilder::String(); |
151 | | |
152 | | bool VariableValueHelper(std::string& out, Json::Value const* value, |
153 | | cmJSONState* state) |
154 | 0 | { |
155 | 0 | if (!value) { |
156 | 0 | out.clear(); |
157 | 0 | return true; |
158 | 0 | } |
159 | | |
160 | 0 | if (value->isBool()) { |
161 | 0 | out = value->asBool() ? "TRUE" : "FALSE"; |
162 | 0 | return true; |
163 | 0 | } |
164 | | |
165 | 0 | return VariableStringHelper(out, value, state); |
166 | 0 | } |
167 | | |
168 | | auto const VariableObjectHelper = |
169 | | JSONHelperBuilder::Object<CacheVariable>( |
170 | | cmCMakePresetsErrors::INVALID_VARIABLE_OBJECT, false) |
171 | | .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) |
172 | | .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); |
173 | | |
174 | | bool VariableHelper(cm::optional<CacheVariable>& out, Json::Value const* value, |
175 | | cmJSONState* state) |
176 | 0 | { |
177 | 0 | if (value->isBool()) { |
178 | 0 | out = CacheVariable{ |
179 | 0 | /*Type=*/"BOOL", |
180 | 0 | /*Value=*/value->asBool() ? "TRUE" : "FALSE", |
181 | 0 | }; |
182 | 0 | return true; |
183 | 0 | } |
184 | 0 | if (value->isString()) { |
185 | 0 | out = CacheVariable{ |
186 | 0 | /*Type=*/"", |
187 | 0 | /*Value=*/value->asString(), |
188 | 0 | }; |
189 | 0 | return true; |
190 | 0 | } |
191 | 0 | if (value->isObject()) { |
192 | 0 | out.emplace(); |
193 | 0 | return VariableObjectHelper(*out, value, state); |
194 | 0 | } |
195 | 0 | if (value->isNull()) { |
196 | 0 | out = cm::nullopt; |
197 | 0 | return true; |
198 | 0 | } |
199 | 0 | cmCMakePresetsErrors::INVALID_VARIABLE(value, state); |
200 | 0 | return false; |
201 | 0 | } |
202 | | |
203 | | auto const VariablesHelper = |
204 | | JSONHelperBuilder::Map<cm::optional<CacheVariable>>( |
205 | | cmCMakePresetsErrors::INVALID_PRESET, VariableHelper); |
206 | | |
207 | | auto const PresetWarningsHelper = |
208 | | JSONHelperBuilder::Object<ConfigurePreset>( |
209 | | JsonErrors::INVALID_NAMED_OBJECT_KEY, false) |
210 | | .Bind("dev"_s, &ConfigurePreset::WarnDev, |
211 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) |
212 | | .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated, |
213 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) |
214 | | .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized, |
215 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) |
216 | | .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli, |
217 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) |
218 | | .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars, |
219 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); |
220 | | |
221 | | auto const PresetErrorsHelper = |
222 | | JSONHelperBuilder::Object<ConfigurePreset>( |
223 | | JsonErrors::INVALID_NAMED_OBJECT_KEY, false) |
224 | | .Bind("dev"_s, &ConfigurePreset::ErrorDev, |
225 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) |
226 | | .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, |
227 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); |
228 | | |
229 | | auto const PresetDebugHelper = |
230 | | JSONHelperBuilder::Object<ConfigurePreset>( |
231 | | JsonErrors::INVALID_NAMED_OBJECT_KEY, false) |
232 | | .Bind("output"_s, &ConfigurePreset::DebugOutput, |
233 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) |
234 | | .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile, |
235 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) |
236 | | .Bind("find"_s, &ConfigurePreset::DebugFind, |
237 | | cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); |
238 | | |
239 | | auto const PresetTraceHelper = |
240 | | JSONHelperBuilder::Object<ConfigurePreset>( |
241 | | cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false) |
242 | | .Bind("mode"_s, &ConfigurePreset::TraceMode, TraceEnableModeHelper, false) |
243 | | .Bind("format"_s, &ConfigurePreset::TraceFormat, TraceOutputFormatHelper, |
244 | | false) |
245 | | .Bind("source"_s, &ConfigurePreset::TraceSource, |
246 | | cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, |
247 | | false) |
248 | | .Bind("redirect"_s, &ConfigurePreset::TraceRedirect, |
249 | | cmCMakePresetsGraphInternal::PresetStringHelper, false); |
250 | | |
251 | | auto const ConfigurePresetHelper = |
252 | | JSONHelperBuilder::Object<ConfigurePreset>( |
253 | | cmCMakePresetsErrors::INVALID_PRESET_OBJECT, false) |
254 | | .Bind("name"_s, &ConfigurePreset::Name, |
255 | | cmCMakePresetsGraphInternal::PresetNameHelper) |
256 | | .Bind("inherits"_s, &ConfigurePreset::Inherits, |
257 | | cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, |
258 | | false) |
259 | | .Bind("hidden"_s, &ConfigurePreset::Hidden, |
260 | | cmCMakePresetsGraphInternal::PresetBoolHelper, false) |
261 | | .Bind<std::nullptr_t>("vendor"_s, nullptr, |
262 | | cmCMakePresetsGraphInternal::VendorHelper( |
263 | | cmCMakePresetsErrors::INVALID_PRESET), |
264 | | false) |
265 | | .Bind("displayName"_s, &ConfigurePreset::DisplayName, |
266 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
267 | | .Bind("description"_s, &ConfigurePreset::Description, |
268 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
269 | | .Bind("generator"_s, &ConfigurePreset::Generator, |
270 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
271 | | .Bind("architecture"_s, ArchitectureHelper, false) |
272 | | .Bind("toolset"_s, ToolsetHelper, false) |
273 | | .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile, |
274 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
275 | | .Bind("graphviz"_s, &ConfigurePreset::GraphVizFile, |
276 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
277 | | .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, |
278 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
279 | | .Bind("installDir"_s, &ConfigurePreset::InstallDir, |
280 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
281 | | .Bind<std::string>("cmakeExecutable"_s, nullptr, |
282 | | cmCMakePresetsGraphInternal::PresetStringHelper, false) |
283 | | .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables, |
284 | | VariablesHelper, false) |
285 | | .Bind("environment"_s, &ConfigurePreset::Environment, |
286 | | cmCMakePresetsGraphInternal::EnvironmentMapHelper, false) |
287 | | .Bind("warnings"_s, PresetWarningsHelper, false) |
288 | | .Bind("errors"_s, PresetErrorsHelper, false) |
289 | | .Bind("debug"_s, PresetDebugHelper, false) |
290 | | .Bind("trace"_s, PresetTraceHelper, false) |
291 | | .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, |
292 | | cmCMakePresetsGraphInternal::PresetConditionHelper, false); |
293 | | } |
294 | | |
295 | | namespace cmCMakePresetsGraphInternal { |
296 | | bool ConfigurePresetsHelper(std::vector<ConfigurePreset>& out, |
297 | | Json::Value const* value, cmJSONState* state) |
298 | 0 | { |
299 | 0 | static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>( |
300 | 0 | cmCMakePresetsErrors::INVALID_PRESETS, ConfigurePresetHelper); |
301 | |
|
302 | 0 | return helper(out, value, state); |
303 | 0 | } |
304 | | } |