cmCMakePresetsGraphReadJSON.cxx 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include <functional>
  4. #include <map>
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include <cm/memory>
  9. #include <cm/optional>
  10. #include <cmext/string_view>
  11. #include <cm3p/json/reader.h>
  12. #include <cm3p/json/value.h>
  13. #include "cmsys/FStream.hxx"
  14. #include "cmCMakePresetsGraph.h"
  15. #include "cmCMakePresetsGraphInternal.h"
  16. #include "cmJSONHelpers.h"
  17. #include "cmVersion.h"
  18. namespace {
  19. using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
  20. using CacheVariable = cmCMakePresetsGraph::CacheVariable;
  21. using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
  22. using BuildPreset = cmCMakePresetsGraph::BuildPreset;
  23. using TestPreset = cmCMakePresetsGraph::TestPreset;
  24. using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
  25. constexpr int MIN_VERSION = 1;
  26. constexpr int MAX_VERSION = 3;
  27. struct CMakeVersion
  28. {
  29. unsigned int Major = 0;
  30. unsigned int Minor = 0;
  31. unsigned int Patch = 0;
  32. };
  33. struct RootPresets
  34. {
  35. CMakeVersion CMakeMinimumRequired;
  36. std::vector<cmCMakePresetsGraph::ConfigurePreset> ConfigurePresets;
  37. std::vector<cmCMakePresetsGraph::BuildPreset> BuildPresets;
  38. std::vector<cmCMakePresetsGraph::TestPreset> TestPresets;
  39. };
  40. std::unique_ptr<cmCMakePresetsGraphInternal::NotCondition> InvertCondition(
  41. std::unique_ptr<cmCMakePresetsGraph::Condition> condition)
  42. {
  43. auto retval = cm::make_unique<cmCMakePresetsGraphInternal::NotCondition>();
  44. retval->SubCondition = std::move(condition);
  45. return retval;
  46. }
  47. auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>(
  48. ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
  49. auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>(
  50. ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
  51. auto const ConditionStringListHelper =
  52. cmJSONVectorHelper<std::string, ReadFileResult>(
  53. ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
  54. ConditionStringHelper);
  55. auto const ConstConditionHelper =
  56. cmJSONObjectHelper<cmCMakePresetsGraphInternal::ConstCondition,
  57. ReadFileResult>(ReadFileResult::READ_OK,
  58. ReadFileResult::INVALID_CONDITION, false)
  59. .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
  60. .Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value,
  61. ConditionBoolHelper, true);
  62. auto const EqualsConditionHelper =
  63. cmJSONObjectHelper<cmCMakePresetsGraphInternal::EqualsCondition,
  64. ReadFileResult>(ReadFileResult::READ_OK,
  65. ReadFileResult::INVALID_CONDITION, false)
  66. .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
  67. .Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs,
  68. ConditionStringHelper, true)
  69. .Bind("rhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Rhs,
  70. ConditionStringHelper, true);
  71. auto const InListConditionHelper =
  72. cmJSONObjectHelper<cmCMakePresetsGraphInternal::InListCondition,
  73. ReadFileResult>(ReadFileResult::READ_OK,
  74. ReadFileResult::INVALID_CONDITION, false)
  75. .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
  76. .Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String,
  77. ConditionStringHelper, true)
  78. .Bind("list"_s, &cmCMakePresetsGraphInternal::InListCondition::List,
  79. ConditionStringListHelper, true);
  80. auto const MatchesConditionHelper =
  81. cmJSONObjectHelper<cmCMakePresetsGraphInternal::MatchesCondition,
  82. ReadFileResult>(ReadFileResult::READ_OK,
  83. ReadFileResult::INVALID_CONDITION, false)
  84. .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
  85. .Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String,
  86. ConditionStringHelper, true)
  87. .Bind("regex"_s, &cmCMakePresetsGraphInternal::MatchesCondition::Regex,
  88. ConditionStringHelper, true);
  89. ReadFileResult SubConditionHelper(
  90. std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
  91. const Json::Value* value);
  92. auto const ListConditionVectorHelper =
  93. cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsGraph::Condition>,
  94. ReadFileResult>(ReadFileResult::READ_OK,
  95. ReadFileResult::INVALID_CONDITION,
  96. SubConditionHelper);
  97. auto const AnyAllOfConditionHelper =
  98. cmJSONObjectHelper<cmCMakePresetsGraphInternal::AnyAllOfCondition,
  99. ReadFileResult>(ReadFileResult::READ_OK,
  100. ReadFileResult::INVALID_CONDITION, false)
  101. .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
  102. .Bind("conditions"_s,
  103. &cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions,
  104. ListConditionVectorHelper);
  105. auto const NotConditionHelper =
  106. cmJSONObjectHelper<cmCMakePresetsGraphInternal::NotCondition,
  107. ReadFileResult>(ReadFileResult::READ_OK,
  108. ReadFileResult::INVALID_CONDITION, false)
  109. .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
  110. .Bind("condition"_s,
  111. &cmCMakePresetsGraphInternal::NotCondition::SubCondition,
  112. SubConditionHelper);
  113. ReadFileResult ConditionHelper(
  114. std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
  115. const Json::Value* value)
  116. {
  117. if (!value) {
  118. out.reset();
  119. return ReadFileResult::READ_OK;
  120. }
  121. if (value->isBool()) {
  122. auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>();
  123. c->Value = value->asBool();
  124. out = std::move(c);
  125. return ReadFileResult::READ_OK;
  126. }
  127. if (value->isNull()) {
  128. out = cm::make_unique<cmCMakePresetsGraphInternal::NullCondition>();
  129. return ReadFileResult::READ_OK;
  130. }
  131. if (value->isObject()) {
  132. if (!value->isMember("type")) {
  133. return ReadFileResult::INVALID_CONDITION;
  134. }
  135. if (!(*value)["type"].isString()) {
  136. return ReadFileResult::INVALID_CONDITION;
  137. }
  138. auto type = (*value)["type"].asString();
  139. if (type == "const") {
  140. auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>();
  141. CHECK_OK(ConstConditionHelper(*c, value));
  142. out = std::move(c);
  143. return ReadFileResult::READ_OK;
  144. }
  145. if (type == "equals" || type == "notEquals") {
  146. auto c = cm::make_unique<cmCMakePresetsGraphInternal::EqualsCondition>();
  147. CHECK_OK(EqualsConditionHelper(*c, value));
  148. out = std::move(c);
  149. if (type == "notEquals") {
  150. out = InvertCondition(std::move(out));
  151. }
  152. return ReadFileResult::READ_OK;
  153. }
  154. if (type == "inList" || type == "notInList") {
  155. auto c = cm::make_unique<cmCMakePresetsGraphInternal::InListCondition>();
  156. CHECK_OK(InListConditionHelper(*c, value));
  157. out = std::move(c);
  158. if (type == "notInList") {
  159. out = InvertCondition(std::move(out));
  160. }
  161. return ReadFileResult::READ_OK;
  162. }
  163. if (type == "matches" || type == "notMatches") {
  164. auto c =
  165. cm::make_unique<cmCMakePresetsGraphInternal::MatchesCondition>();
  166. CHECK_OK(MatchesConditionHelper(*c, value));
  167. out = std::move(c);
  168. if (type == "notMatches") {
  169. out = InvertCondition(std::move(out));
  170. }
  171. return ReadFileResult::READ_OK;
  172. }
  173. if (type == "anyOf" || type == "allOf") {
  174. auto c =
  175. cm::make_unique<cmCMakePresetsGraphInternal::AnyAllOfCondition>();
  176. c->StopValue = (type == "anyOf");
  177. CHECK_OK(AnyAllOfConditionHelper(*c, value));
  178. out = std::move(c);
  179. return ReadFileResult::READ_OK;
  180. }
  181. if (type == "not") {
  182. auto c = cm::make_unique<cmCMakePresetsGraphInternal::NotCondition>();
  183. CHECK_OK(NotConditionHelper(*c, value));
  184. out = std::move(c);
  185. return ReadFileResult::READ_OK;
  186. }
  187. }
  188. return ReadFileResult::INVALID_CONDITION;
  189. }
  190. ReadFileResult PresetConditionHelper(
  191. std::shared_ptr<cmCMakePresetsGraph::Condition>& out,
  192. const Json::Value* value)
  193. {
  194. std::unique_ptr<cmCMakePresetsGraph::Condition> ptr;
  195. auto result = ConditionHelper(ptr, value);
  196. out = std::move(ptr);
  197. return result;
  198. }
  199. ReadFileResult SubConditionHelper(
  200. std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
  201. const Json::Value* value)
  202. {
  203. std::unique_ptr<cmCMakePresetsGraph::Condition> ptr;
  204. auto result = ConditionHelper(ptr, value);
  205. if (ptr && ptr->IsNull()) {
  206. return ReadFileResult::INVALID_CONDITION;
  207. }
  208. out = std::move(ptr);
  209. return result;
  210. }
  211. cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error)
  212. {
  213. return [error](std::nullptr_t& /*out*/,
  214. const Json::Value* value) -> ReadFileResult {
  215. if (!value) {
  216. return ReadFileResult::READ_OK;
  217. }
  218. if (!value->isObject()) {
  219. return error;
  220. }
  221. return ReadFileResult::READ_OK;
  222. };
  223. }
  224. auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>(
  225. ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
  226. auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>(
  227. ReadFileResult::NO_VERSION, VersionIntHelper);
  228. auto const RootVersionHelper =
  229. cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK,
  230. ReadFileResult::INVALID_ROOT)
  231. .Bind("version"_s, VersionHelper, false);
  232. auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>(
  233. ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE);
  234. ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value)
  235. {
  236. if (!value) {
  237. out.clear();
  238. return ReadFileResult::READ_OK;
  239. }
  240. if (value->isBool()) {
  241. out = value->asBool() ? "TRUE" : "FALSE";
  242. return ReadFileResult::READ_OK;
  243. }
  244. return VariableStringHelper(out, value);
  245. }
  246. auto const VariableObjectHelper =
  247. cmJSONObjectHelper<CacheVariable, ReadFileResult>(
  248. ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false)
  249. .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
  250. .Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
  251. ReadFileResult VariableHelper(cm::optional<CacheVariable>& out,
  252. const Json::Value* value)
  253. {
  254. if (value->isBool()) {
  255. out = CacheVariable{
  256. /*Type=*/"BOOL",
  257. /*Value=*/value->asBool() ? "TRUE" : "FALSE",
  258. };
  259. return ReadFileResult::READ_OK;
  260. }
  261. if (value->isString()) {
  262. out = CacheVariable{
  263. /*Type=*/"",
  264. /*Value=*/value->asString(),
  265. };
  266. return ReadFileResult::READ_OK;
  267. }
  268. if (value->isObject()) {
  269. out.emplace();
  270. return VariableObjectHelper(*out, value);
  271. }
  272. if (value->isNull()) {
  273. out = cm::nullopt;
  274. return ReadFileResult::READ_OK;
  275. }
  276. return ReadFileResult::INVALID_VARIABLE;
  277. }
  278. auto const VariablesHelper =
  279. cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>(
  280. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper);
  281. auto const PresetStringHelper = cmJSONStringHelper<ReadFileResult>(
  282. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
  283. ReadFileResult EnvironmentHelper(cm::optional<std::string>& out,
  284. const Json::Value* value)
  285. {
  286. if (!value || value->isNull()) {
  287. out = cm::nullopt;
  288. return ReadFileResult::READ_OK;
  289. }
  290. if (value->isString()) {
  291. out = value->asString();
  292. return ReadFileResult::READ_OK;
  293. }
  294. return ReadFileResult::INVALID_PRESET;
  295. }
  296. auto const EnvironmentMapHelper =
  297. cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>(
  298. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
  299. EnvironmentHelper);
  300. auto const PresetVectorStringHelper =
  301. cmJSONVectorHelper<std::string, ReadFileResult>(
  302. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
  303. PresetStringHelper);
  304. ReadFileResult PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out,
  305. const Json::Value* value)
  306. {
  307. out.clear();
  308. if (!value) {
  309. return ReadFileResult::READ_OK;
  310. }
  311. if (value->isString()) {
  312. out.push_back(value->asString());
  313. return ReadFileResult::READ_OK;
  314. }
  315. return PresetVectorStringHelper(out, value);
  316. }
  317. auto const PresetBoolHelper = cmJSONBoolHelper<ReadFileResult>(
  318. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
  319. auto const PresetOptionalBoolHelper =
  320. cmJSONOptionalHelper<bool, ReadFileResult>(ReadFileResult::READ_OK,
  321. PresetBoolHelper);
  322. auto const PresetIntHelper = cmJSONIntHelper<ReadFileResult>(
  323. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
  324. auto const PresetOptionalIntHelper = cmJSONOptionalHelper<int, ReadFileResult>(
  325. ReadFileResult::READ_OK, PresetIntHelper);
  326. auto const PresetVectorIntHelper = cmJSONVectorHelper<int, ReadFileResult>(
  327. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper);
  328. auto const PresetWarningsHelper =
  329. cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
  330. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  331. .Bind("dev"_s, &ConfigurePreset::WarnDev, PresetOptionalBoolHelper, false)
  332. .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated,
  333. PresetOptionalBoolHelper, false)
  334. .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized,
  335. PresetOptionalBoolHelper, false)
  336. .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli,
  337. PresetOptionalBoolHelper, false)
  338. .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars,
  339. PresetOptionalBoolHelper, false);
  340. auto const PresetErrorsHelper =
  341. cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
  342. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  343. .Bind("dev"_s, &ConfigurePreset::ErrorDev, PresetOptionalBoolHelper, false)
  344. .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated,
  345. PresetOptionalBoolHelper, false);
  346. auto const PresetDebugHelper =
  347. cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
  348. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  349. .Bind("output"_s, &ConfigurePreset::DebugOutput, PresetOptionalBoolHelper,
  350. false)
  351. .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile,
  352. PresetOptionalBoolHelper, false)
  353. .Bind("find"_s, &ConfigurePreset::DebugFind, PresetOptionalBoolHelper,
  354. false);
  355. ReadFileResult ArchToolsetStrategyHelper(
  356. cm::optional<ArchToolsetStrategy>& out, const Json::Value* value)
  357. {
  358. if (!value) {
  359. out = cm::nullopt;
  360. return ReadFileResult::READ_OK;
  361. }
  362. if (!value->isString()) {
  363. return ReadFileResult::INVALID_PRESET;
  364. }
  365. if (value->asString() == "set") {
  366. out = ArchToolsetStrategy::Set;
  367. return ReadFileResult::READ_OK;
  368. }
  369. if (value->asString() == "external") {
  370. out = ArchToolsetStrategy::External;
  371. return ReadFileResult::READ_OK;
  372. }
  373. return ReadFileResult::INVALID_PRESET;
  374. }
  375. std::function<ReadFileResult(ConfigurePreset&, const Json::Value*)>
  376. ArchToolsetHelper(
  377. std::string ConfigurePreset::*valueField,
  378. cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField)
  379. {
  380. auto const objectHelper =
  381. cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
  382. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  383. .Bind("value", valueField, PresetStringHelper, false)
  384. .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false);
  385. return [valueField, strategyField, objectHelper](
  386. ConfigurePreset& out, const Json::Value* value) -> ReadFileResult {
  387. if (!value) {
  388. (out.*valueField).clear();
  389. out.*strategyField = cm::nullopt;
  390. return ReadFileResult::READ_OK;
  391. }
  392. if (value->isString()) {
  393. out.*valueField = value->asString();
  394. out.*strategyField = cm::nullopt;
  395. return ReadFileResult::READ_OK;
  396. }
  397. if (value->isObject()) {
  398. return objectHelper(out, value);
  399. }
  400. return ReadFileResult::INVALID_PRESET;
  401. };
  402. }
  403. auto const ArchitectureHelper = ArchToolsetHelper(
  404. &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy);
  405. auto const ToolsetHelper = ArchToolsetHelper(
  406. &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy);
  407. auto const ConfigurePresetHelper =
  408. cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
  409. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  410. .Bind("name"_s, &ConfigurePreset::Name, PresetStringHelper)
  411. .Bind("inherits"_s, &ConfigurePreset::Inherits,
  412. PresetVectorOneOrMoreStringHelper, false)
  413. .Bind("hidden"_s, &ConfigurePreset::Hidden, PresetBoolHelper, false)
  414. .Bind<std::nullptr_t>("vendor"_s, nullptr,
  415. VendorHelper(ReadFileResult::INVALID_PRESET), false)
  416. .Bind("displayName"_s, &ConfigurePreset::DisplayName, PresetStringHelper,
  417. false)
  418. .Bind("description"_s, &ConfigurePreset::Description, PresetStringHelper,
  419. false)
  420. .Bind("generator"_s, &ConfigurePreset::Generator, PresetStringHelper,
  421. false)
  422. .Bind("architecture"_s, ArchitectureHelper, false)
  423. .Bind("toolset"_s, ToolsetHelper, false)
  424. .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile,
  425. PresetStringHelper, false)
  426. .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, PresetStringHelper,
  427. false)
  428. .Bind("installDir"_s, &ConfigurePreset::InstallDir, PresetStringHelper,
  429. false)
  430. .Bind<std::string>("cmakeExecutable"_s, nullptr, PresetStringHelper, false)
  431. .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables,
  432. VariablesHelper, false)
  433. .Bind("environment"_s, &ConfigurePreset::Environment, EnvironmentMapHelper,
  434. false)
  435. .Bind("warnings"_s, PresetWarningsHelper, false)
  436. .Bind("errors"_s, PresetErrorsHelper, false)
  437. .Bind("debug"_s, PresetDebugHelper, false)
  438. .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator,
  439. PresetConditionHelper, false);
  440. auto const BuildPresetHelper =
  441. cmJSONObjectHelper<BuildPreset, ReadFileResult>(
  442. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  443. .Bind("name"_s, &BuildPreset::Name, PresetStringHelper)
  444. .Bind("inherits"_s, &BuildPreset::Inherits,
  445. PresetVectorOneOrMoreStringHelper, false)
  446. .Bind("hidden"_s, &BuildPreset::Hidden, PresetBoolHelper, false)
  447. .Bind<std::nullptr_t>("vendor"_s, nullptr,
  448. VendorHelper(ReadFileResult::INVALID_PRESET), false)
  449. .Bind("displayName"_s, &BuildPreset::DisplayName, PresetStringHelper,
  450. false)
  451. .Bind("description"_s, &BuildPreset::Description, PresetStringHelper,
  452. false)
  453. .Bind("environment"_s, &BuildPreset::Environment, EnvironmentMapHelper,
  454. false)
  455. .Bind("configurePreset"_s, &BuildPreset::ConfigurePreset,
  456. PresetStringHelper, false)
  457. .Bind("inheritConfigureEnvironment"_s,
  458. &BuildPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper,
  459. false)
  460. .Bind("jobs"_s, &BuildPreset::Jobs, PresetOptionalIntHelper, false)
  461. .Bind("targets"_s, &BuildPreset::Targets,
  462. PresetVectorOneOrMoreStringHelper, false)
  463. .Bind("configuration"_s, &BuildPreset::Configuration, PresetStringHelper,
  464. false)
  465. .Bind("cleanFirst"_s, &BuildPreset::CleanFirst, PresetOptionalBoolHelper,
  466. false)
  467. .Bind("verbose"_s, &BuildPreset::Verbose, PresetOptionalBoolHelper, false)
  468. .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions,
  469. PresetVectorStringHelper, false)
  470. .Bind("condition"_s, &BuildPreset::ConditionEvaluator,
  471. PresetConditionHelper, false);
  472. ReadFileResult TestPresetOutputVerbosityHelper(
  473. TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value)
  474. {
  475. if (!value) {
  476. out = TestPreset::OutputOptions::VerbosityEnum::Default;
  477. return ReadFileResult::READ_OK;
  478. }
  479. if (!value->isString()) {
  480. return ReadFileResult::INVALID_PRESET;
  481. }
  482. if (value->asString() == "default") {
  483. out = TestPreset::OutputOptions::VerbosityEnum::Default;
  484. return ReadFileResult::READ_OK;
  485. }
  486. if (value->asString() == "verbose") {
  487. out = TestPreset::OutputOptions::VerbosityEnum::Verbose;
  488. return ReadFileResult::READ_OK;
  489. }
  490. if (value->asString() == "extra") {
  491. out = TestPreset::OutputOptions::VerbosityEnum::Extra;
  492. return ReadFileResult::READ_OK;
  493. }
  494. return ReadFileResult::INVALID_PRESET;
  495. }
  496. auto const TestPresetOptionalOutputVerbosityHelper =
  497. cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum,
  498. ReadFileResult>(ReadFileResult::READ_OK,
  499. TestPresetOutputVerbosityHelper);
  500. auto const TestPresetOptionalOutputHelper =
  501. cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>(
  502. ReadFileResult::READ_OK,
  503. cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>(
  504. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  505. .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress,
  506. PresetOptionalBoolHelper, false)
  507. .Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity,
  508. TestPresetOptionalOutputVerbosityHelper, false)
  509. .Bind("debug"_s, &TestPreset::OutputOptions::Debug,
  510. PresetOptionalBoolHelper, false)
  511. .Bind("outputOnFailure"_s, &TestPreset::OutputOptions::OutputOnFailure,
  512. PresetOptionalBoolHelper, false)
  513. .Bind("quiet"_s, &TestPreset::OutputOptions::Quiet,
  514. PresetOptionalBoolHelper, false)
  515. .Bind("outputLogFile"_s, &TestPreset::OutputOptions::OutputLogFile,
  516. PresetStringHelper, false)
  517. .Bind("labelSummary"_s, &TestPreset::OutputOptions::LabelSummary,
  518. PresetOptionalBoolHelper, false)
  519. .Bind("subprojectSummary"_s,
  520. &TestPreset::OutputOptions::SubprojectSummary,
  521. PresetOptionalBoolHelper, false)
  522. .Bind("maxPassedTestOutputSize"_s,
  523. &TestPreset::OutputOptions::MaxPassedTestOutputSize,
  524. PresetOptionalIntHelper, false)
  525. .Bind("maxFailedTestOutputSize"_s,
  526. &TestPreset::OutputOptions::MaxFailedTestOutputSize,
  527. PresetOptionalIntHelper, false)
  528. .Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth,
  529. PresetOptionalIntHelper, false));
  530. auto const TestPresetOptionalFilterIncludeIndexObjectHelper =
  531. cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions,
  532. ReadFileResult>(
  533. ReadFileResult::READ_OK,
  534. cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions,
  535. ReadFileResult>(ReadFileResult::READ_OK,
  536. ReadFileResult::INVALID_PRESET)
  537. .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start,
  538. PresetOptionalIntHelper, false)
  539. .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End,
  540. PresetOptionalIntHelper, false)
  541. .Bind("stride"_s, &TestPreset::IncludeOptions::IndexOptions::Stride,
  542. PresetOptionalIntHelper, false)
  543. .Bind("specificTests"_s,
  544. &TestPreset::IncludeOptions::IndexOptions::SpecificTests,
  545. PresetVectorIntHelper, false));
  546. ReadFileResult TestPresetOptionalFilterIncludeIndexHelper(
  547. cm::optional<TestPreset::IncludeOptions::IndexOptions>& out,
  548. const Json::Value* value)
  549. {
  550. if (!value) {
  551. out = cm::nullopt;
  552. return ReadFileResult::READ_OK;
  553. }
  554. if (value->isString()) {
  555. out.emplace();
  556. out->IndexFile = value->asString();
  557. return ReadFileResult::READ_OK;
  558. }
  559. if (value->isObject()) {
  560. return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value);
  561. }
  562. return ReadFileResult::INVALID_PRESET;
  563. }
  564. auto const TestPresetOptionalFilterIncludeHelper =
  565. cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>(
  566. ReadFileResult::READ_OK,
  567. cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>(
  568. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
  569. .Bind("name"_s, &TestPreset::IncludeOptions::Name, PresetStringHelper,
  570. false)
  571. .Bind("label"_s, &TestPreset::IncludeOptions::Label, PresetStringHelper,
  572. false)
  573. .Bind("index"_s, &TestPreset::IncludeOptions::Index,
  574. TestPresetOptionalFilterIncludeIndexHelper, false)
  575. .Bind("useUnion"_s, &TestPreset::IncludeOptions::UseUnion,
  576. PresetOptionalBoolHelper, false));
  577. auto const TestPresetOptionalFilterExcludeFixturesHelper =
  578. cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions,
  579. ReadFileResult>(
  580. ReadFileResult::READ_OK,
  581. cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions,
  582. ReadFileResult>(ReadFileResult::READ_OK,
  583. ReadFileResult::INVALID_PRESET)
  584. .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any,
  585. PresetStringHelper, false)
  586. .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup,
  587. PresetStringHelper, false)
  588. .Bind("cleanup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Cleanup,
  589. PresetStringHelper, false));
  590. auto const TestPresetOptionalFilterExcludeHelper =
  591. cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>(
  592. ReadFileResult::READ_OK,
  593. cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>(
  594. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
  595. .Bind("name"_s, &TestPreset::ExcludeOptions::Name, PresetStringHelper,
  596. false)
  597. .Bind("label"_s, &TestPreset::ExcludeOptions::Label, PresetStringHelper,
  598. false)
  599. .Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures,
  600. TestPresetOptionalFilterExcludeFixturesHelper, false));
  601. ReadFileResult TestPresetExecutionShowOnlyHelper(
  602. TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value)
  603. {
  604. if (!value || !value->isString()) {
  605. return ReadFileResult::INVALID_PRESET;
  606. }
  607. if (value->asString() == "human") {
  608. out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human;
  609. return ReadFileResult::READ_OK;
  610. }
  611. if (value->asString() == "json-v1") {
  612. out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1;
  613. return ReadFileResult::READ_OK;
  614. }
  615. return ReadFileResult::INVALID_PRESET;
  616. }
  617. auto const TestPresetOptionalExecutionShowOnlyHelper =
  618. cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum,
  619. ReadFileResult>(ReadFileResult::READ_OK,
  620. TestPresetExecutionShowOnlyHelper);
  621. ReadFileResult TestPresetExecutionModeHelper(
  622. TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out,
  623. const Json::Value* value)
  624. {
  625. if (!value) {
  626. return ReadFileResult::READ_OK;
  627. }
  628. if (!value->isString()) {
  629. return ReadFileResult::INVALID_PRESET;
  630. }
  631. if (value->asString() == "until-fail") {
  632. out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail;
  633. return ReadFileResult::READ_OK;
  634. }
  635. if (value->asString() == "until-pass") {
  636. out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass;
  637. return ReadFileResult::READ_OK;
  638. }
  639. if (value->asString() == "after-timeout") {
  640. out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout;
  641. return ReadFileResult::READ_OK;
  642. }
  643. return ReadFileResult::INVALID_PRESET;
  644. }
  645. auto const TestPresetOptionalExecutionRepeatHelper =
  646. cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions,
  647. ReadFileResult>(
  648. ReadFileResult::READ_OK,
  649. cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions,
  650. ReadFileResult>(ReadFileResult::READ_OK,
  651. ReadFileResult::INVALID_PRESET)
  652. .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode,
  653. TestPresetExecutionModeHelper, true)
  654. .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count,
  655. PresetIntHelper, true));
  656. ReadFileResult TestPresetExecutionNoTestsActionHelper(
  657. TestPreset::ExecutionOptions::NoTestsActionEnum& out,
  658. const Json::Value* value)
  659. {
  660. if (!value) {
  661. out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default;
  662. return ReadFileResult::READ_OK;
  663. }
  664. if (!value->isString()) {
  665. return ReadFileResult::INVALID_PRESET;
  666. }
  667. if (value->asString() == "default") {
  668. out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default;
  669. return ReadFileResult::READ_OK;
  670. }
  671. if (value->asString() == "error") {
  672. out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error;
  673. return ReadFileResult::READ_OK;
  674. }
  675. if (value->asString() == "ignore") {
  676. out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore;
  677. return ReadFileResult::READ_OK;
  678. }
  679. return ReadFileResult::INVALID_PRESET;
  680. }
  681. auto const TestPresetOptionalExecutionNoTestsActionHelper =
  682. cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum,
  683. ReadFileResult>(ReadFileResult::READ_OK,
  684. TestPresetExecutionNoTestsActionHelper);
  685. auto const TestPresetExecutionHelper =
  686. cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>(
  687. ReadFileResult::READ_OK,
  688. cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>(
  689. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
  690. .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure,
  691. PresetOptionalBoolHelper, false)
  692. .Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover,
  693. PresetOptionalBoolHelper, false)
  694. .Bind("jobs"_s, &TestPreset::ExecutionOptions::Jobs,
  695. PresetOptionalIntHelper, false)
  696. .Bind("resourceSpecFile"_s,
  697. &TestPreset::ExecutionOptions::ResourceSpecFile,
  698. PresetStringHelper, false)
  699. .Bind("testLoad"_s, &TestPreset::ExecutionOptions::TestLoad,
  700. PresetOptionalIntHelper, false)
  701. .Bind("showOnly"_s, &TestPreset::ExecutionOptions::ShowOnly,
  702. TestPresetOptionalExecutionShowOnlyHelper, false)
  703. .Bind("repeat"_s, &TestPreset::ExecutionOptions::Repeat,
  704. TestPresetOptionalExecutionRepeatHelper, false)
  705. .Bind("interactiveDebugging"_s,
  706. &TestPreset::ExecutionOptions::InteractiveDebugging,
  707. PresetOptionalBoolHelper, false)
  708. .Bind("scheduleRandom"_s, &TestPreset::ExecutionOptions::ScheduleRandom,
  709. PresetOptionalBoolHelper, false)
  710. .Bind("timeout"_s, &TestPreset::ExecutionOptions::Timeout,
  711. PresetOptionalIntHelper, false)
  712. .Bind("noTestsAction"_s, &TestPreset::ExecutionOptions::NoTestsAction,
  713. TestPresetOptionalExecutionNoTestsActionHelper, false));
  714. auto const TestPresetFilterHelper =
  715. cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>(
  716. ReadFileResult::READ_OK,
  717. cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>(
  718. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
  719. .Bind("include"_s, &TestPreset::FilterOptions::Include,
  720. TestPresetOptionalFilterIncludeHelper, false)
  721. .Bind("exclude"_s, &TestPreset::FilterOptions::Exclude,
  722. TestPresetOptionalFilterExcludeHelper, false));
  723. auto const TestPresetHelper =
  724. cmJSONObjectHelper<TestPreset, ReadFileResult>(
  725. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
  726. .Bind("name"_s, &TestPreset::Name, PresetStringHelper)
  727. .Bind("inherits"_s, &TestPreset::Inherits,
  728. PresetVectorOneOrMoreStringHelper, false)
  729. .Bind("hidden"_s, &TestPreset::Hidden, PresetBoolHelper, false)
  730. .Bind<std::nullptr_t>("vendor"_s, nullptr,
  731. VendorHelper(ReadFileResult::INVALID_PRESET), false)
  732. .Bind("displayName"_s, &TestPreset::DisplayName, PresetStringHelper, false)
  733. .Bind("description"_s, &TestPreset::Description, PresetStringHelper, false)
  734. .Bind("environment"_s, &TestPreset::Environment, EnvironmentMapHelper,
  735. false)
  736. .Bind("configurePreset"_s, &TestPreset::ConfigurePreset,
  737. PresetStringHelper, false)
  738. .Bind("inheritConfigureEnvironment"_s,
  739. &TestPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper,
  740. false)
  741. .Bind("configuration"_s, &TestPreset::Configuration, PresetStringHelper,
  742. false)
  743. .Bind("overwriteConfigurationFile"_s,
  744. &TestPreset::OverwriteConfigurationFile, PresetVectorStringHelper,
  745. false)
  746. .Bind("output"_s, &TestPreset::Output, TestPresetOptionalOutputHelper,
  747. false)
  748. .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false)
  749. .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper,
  750. false)
  751. .Bind("condition"_s, &TestPreset::ConditionEvaluator,
  752. PresetConditionHelper, false);
  753. auto const ConfigurePresetsHelper =
  754. cmJSONVectorHelper<ConfigurePreset, ReadFileResult>(
  755. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
  756. ConfigurePresetHelper);
  757. auto const BuildPresetsHelper =
  758. cmJSONVectorHelper<BuildPreset, ReadFileResult>(
  759. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
  760. BuildPresetHelper);
  761. auto const TestPresetsHelper = cmJSONVectorHelper<TestPreset, ReadFileResult>(
  762. ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, TestPresetHelper);
  763. auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>(
  764. ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
  765. auto const CMakeVersionHelper =
  766. cmJSONObjectHelper<CMakeVersion, ReadFileResult>(
  767. ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false)
  768. .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false)
  769. .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false)
  770. .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false);
  771. auto const RootPresetsHelper =
  772. cmJSONObjectHelper<RootPresets, ReadFileResult>(
  773. ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false)
  774. .Bind<int>("version"_s, nullptr, VersionHelper)
  775. .Bind("configurePresets"_s, &RootPresets::ConfigurePresets,
  776. ConfigurePresetsHelper, false)
  777. .Bind("buildPresets"_s, &RootPresets::BuildPresets, BuildPresetsHelper,
  778. false)
  779. .Bind("testPresets"_s, &RootPresets::TestPresets, TestPresetsHelper, false)
  780. .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired,
  781. CMakeVersionHelper, false)
  782. .Bind<std::nullptr_t>("vendor"_s, nullptr,
  783. VendorHelper(ReadFileResult::INVALID_ROOT), false);
  784. }
  785. cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
  786. const std::string& filename, bool user)
  787. {
  788. cmsys::ifstream fin(filename.c_str());
  789. if (!fin) {
  790. return ReadFileResult::FILE_NOT_FOUND;
  791. }
  792. // If there's a BOM, toss it.
  793. cmsys::FStream::ReadBOM(fin);
  794. Json::Value root;
  795. Json::CharReaderBuilder builder;
  796. Json::CharReaderBuilder::strictMode(&builder.settings_);
  797. if (!Json::parseFromStream(builder, fin, &root, nullptr)) {
  798. return ReadFileResult::JSON_PARSE_ERROR;
  799. }
  800. int v = 0;
  801. auto result = RootVersionHelper(v, &root);
  802. if (result != ReadFileResult::READ_OK) {
  803. return result;
  804. }
  805. if (v < MIN_VERSION || v > MAX_VERSION) {
  806. return ReadFileResult::UNRECOGNIZED_VERSION;
  807. }
  808. if (user) {
  809. this->UserVersion = v;
  810. } else {
  811. this->Version = v;
  812. }
  813. // Support for build and test presets added in version 2.
  814. if (v < 2 &&
  815. (root.isMember("buildPresets") || root.isMember("testPresets"))) {
  816. return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED;
  817. }
  818. RootPresets presets;
  819. if ((result = RootPresetsHelper(presets, &root)) !=
  820. ReadFileResult::READ_OK) {
  821. return result;
  822. }
  823. unsigned int currentMajor = cmVersion::GetMajorVersion();
  824. unsigned int currentMinor = cmVersion::GetMinorVersion();
  825. unsigned int currentPatch = cmVersion::GetPatchVersion();
  826. auto const& required = presets.CMakeMinimumRequired;
  827. if (required.Major > currentMajor ||
  828. (required.Major == currentMajor &&
  829. (required.Minor > currentMinor ||
  830. (required.Minor == currentMinor &&
  831. (required.Patch > currentPatch))))) {
  832. return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION;
  833. }
  834. for (auto& preset : presets.ConfigurePresets) {
  835. preset.User = user;
  836. if (preset.Name.empty()) {
  837. return ReadFileResult::INVALID_PRESET;
  838. }
  839. PresetPair<ConfigurePreset> presetPair;
  840. presetPair.Unexpanded = preset;
  841. presetPair.Expanded = cm::nullopt;
  842. if (!this->ConfigurePresets
  843. .emplace(std::make_pair(preset.Name, presetPair))
  844. .second) {
  845. return ReadFileResult::DUPLICATE_PRESETS;
  846. }
  847. // Support for installDir presets added in version 3.
  848. if (v < 3 && !preset.InstallDir.empty()) {
  849. return ReadFileResult::INSTALL_PREFIX_UNSUPPORTED;
  850. }
  851. // Support for conditions added in version 3.
  852. if (v < 3 && preset.ConditionEvaluator) {
  853. return ReadFileResult::CONDITION_UNSUPPORTED;
  854. }
  855. // Support for toolchainFile presets added in version 3.
  856. if (v < 3 && !preset.ToolchainFile.empty()) {
  857. return ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED;
  858. }
  859. this->ConfigurePresetOrder.push_back(preset.Name);
  860. }
  861. for (auto& preset : presets.BuildPresets) {
  862. preset.User = user;
  863. if (preset.Name.empty()) {
  864. return ReadFileResult::INVALID_PRESET;
  865. }
  866. PresetPair<BuildPreset> presetPair;
  867. presetPair.Unexpanded = preset;
  868. presetPair.Expanded = cm::nullopt;
  869. if (!this->BuildPresets.emplace(preset.Name, presetPair).second) {
  870. return ReadFileResult::DUPLICATE_PRESETS;
  871. }
  872. // Support for conditions added in version 3.
  873. if (v < 3 && preset.ConditionEvaluator) {
  874. return ReadFileResult::CONDITION_UNSUPPORTED;
  875. }
  876. this->BuildPresetOrder.push_back(preset.Name);
  877. }
  878. for (auto& preset : presets.TestPresets) {
  879. preset.User = user;
  880. if (preset.Name.empty()) {
  881. return ReadFileResult::INVALID_PRESET;
  882. }
  883. PresetPair<TestPreset> presetPair;
  884. presetPair.Unexpanded = preset;
  885. presetPair.Expanded = cm::nullopt;
  886. if (!this->TestPresets.emplace(preset.Name, presetPair).second) {
  887. return ReadFileResult::DUPLICATE_PRESETS;
  888. }
  889. // Support for conditions added in version 3.
  890. if (v < 3 && preset.ConditionEvaluator) {
  891. return ReadFileResult::CONDITION_UNSUPPORTED;
  892. }
  893. this->TestPresetOrder.push_back(preset.Name);
  894. }
  895. return ReadFileResult::READ_OK;
  896. }