1
0

cmCMakePresetsGraphReadJSONConfigurePresets.cxx 10 KB

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