| #include "cmInstrumentationQuery.h" | 
 |  | 
 | #include <algorithm> | 
 | #include <ctime> | 
 | #include <functional> | 
 | #include <iostream> | 
 | #include <iterator> | 
 | #include <set> | 
 | #include <vector> | 
 |  | 
 | #include <cmext/string_view> | 
 |  | 
 | #include <cm3p/json/value.h> | 
 |  | 
 | #include "cmJSONHelpers.h" | 
 | #include "cmStringAlgorithms.h" | 
 |  | 
 | std::vector<std::string> const cmInstrumentationQuery::OptionString{ | 
 |   "staticSystemInformation", "dynamicSystemInformation", "cdashSubmit", | 
 |   "cdashVerbose", "trace" | 
 | }; | 
 | std::vector<std::string> const cmInstrumentationQuery::HookString{ | 
 |   "postGenerate",     "preBuild",        "postBuild", | 
 |   "preCMakeBuild",    "postCMakeBuild",  "postCTest", | 
 |   "postCMakeInstall", "prepareForCDash", "manual" | 
 | }; | 
 |  | 
 | namespace ErrorMessages { | 
 | using ErrorGenerator = | 
 |   std::function<void(Json::Value const*, cmJSONState* state)>; | 
 | ErrorGenerator ErrorGeneratorBuilder(std::string const& errorMessage) | 
 | { | 
 |   return [errorMessage](Json::Value const* value, cmJSONState* state) -> void { | 
 |     state->AddErrorAtValue(errorMessage, value); | 
 |   }; | 
 | }; | 
 |  | 
 | static ErrorGenerator InvalidArray = ErrorGeneratorBuilder("Invalid Array"); | 
 | JsonErrors::ErrorGenerator InvalidRootQueryObject( | 
 |   JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields) | 
 | { | 
 |   return JsonErrors::INVALID_NAMED_OBJECT( | 
 |     [](Json::Value const*, cmJSONState*) -> std::string { | 
 |       return "root object"; | 
 |     })(errorType, extraFields); | 
 | } | 
 | }; | 
 |  | 
 | using JSONHelperBuilder = cmJSONHelperBuilder; | 
 |  | 
 | template <typename E> | 
 | static std::function<bool(E&, Json::Value const*, cmJSONState*)> EnumHelper( | 
 |   std::vector<std::string> const toString, std::string const& type) | 
 | { | 
 |   return [toString, type](E& out, Json::Value const* value, | 
 |                           cmJSONState* state) -> bool { | 
 |     for (size_t i = 0; i < toString.size(); ++i) { | 
 |       if (value->asString() == toString[i]) { | 
 |         out = (E)i; | 
 |         return true; | 
 |       } | 
 |     } | 
 |     state->AddErrorAtValue( | 
 |       cmStrCat("Not a valid ", type, ": \"", value->asString(), '"'), value); | 
 |     return false; | 
 |   }; | 
 | } | 
 | static auto const OptionHelper = EnumHelper<cmInstrumentationQuery::Option>( | 
 |   cmInstrumentationQuery::OptionString, "option"); | 
 | static auto const QueryListHelper = | 
 |   JSONHelperBuilder::Vector<cmInstrumentationQuery::Option>( | 
 |     ErrorMessages::InvalidArray, OptionHelper); | 
 | static auto const HookHelper = EnumHelper<cmInstrumentationQuery::Hook>( | 
 |   cmInstrumentationQuery::HookString, "hook"); | 
 | static auto const HookListHelper = | 
 |   JSONHelperBuilder::Vector<cmInstrumentationQuery::Hook>( | 
 |     ErrorMessages::InvalidArray, HookHelper); | 
 | static auto const CallbackHelper = JSONHelperBuilder::String(); | 
 | static auto const CallbackListHelper = JSONHelperBuilder::Vector<std::string>( | 
 |   ErrorMessages::InvalidArray, CallbackHelper); | 
 | static auto const VersionHelper = JSONHelperBuilder::Int(); | 
 |  | 
 | using QueryRoot = cmInstrumentationQuery::QueryJSONRoot; | 
 |  | 
 | static auto const QueryRootHelper = | 
 |   JSONHelperBuilder::Object<QueryRoot>(ErrorMessages::InvalidRootQueryObject, | 
 |                                        false) | 
 |     .Bind("version"_s, &QueryRoot::version, VersionHelper, true) | 
 |     .Bind("options"_s, &QueryRoot::options, QueryListHelper, false) | 
 |     .Bind("hooks"_s, &QueryRoot::hooks, HookListHelper, false) | 
 |     .Bind("callbacks"_s, &QueryRoot::callbacks, CallbackListHelper, false); | 
 |  | 
 | bool cmInstrumentationQuery::ReadJSON(std::string const& filename, | 
 |                                       std::string& errorMessage, | 
 |                                       std::set<Option>& options, | 
 |                                       std::set<Hook>& hooks, | 
 |                                       std::vector<std::string>& callbacks) | 
 | { | 
 |   Json::Value root; | 
 |   this->parseState = cmJSONState(filename, &root); | 
 |   if (!this->parseState.errors.empty()) { | 
 |     std::cerr << this->parseState.GetErrorMessage(true) << std::endl; | 
 |     return false; | 
 |   } | 
 |   if (!QueryRootHelper(this->queryRoot, &root, &this->parseState)) { | 
 |     errorMessage = this->parseState.GetErrorMessage(true); | 
 |     return false; | 
 |   } | 
 |   std::move(this->queryRoot.options.begin(), this->queryRoot.options.end(), | 
 |             std::inserter(options, options.end())); | 
 |   std::move(this->queryRoot.hooks.begin(), this->queryRoot.hooks.end(), | 
 |             std::inserter(hooks, hooks.end())); | 
 |   std::move(this->queryRoot.callbacks.begin(), this->queryRoot.callbacks.end(), | 
 |             std::back_inserter(callbacks)); | 
 |   return true; | 
 | } |