mirror of
https://github.com/Kitware/CMake.git
synced 2025-05-10 07:10:32 +08:00
116 lines
4.2 KiB
C++
116 lines
4.2 KiB
C++
#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::QueryString{
|
|
"staticSystemInformation", "dynamicSystemInformation"
|
|
};
|
|
std::vector<std::string> const cmInstrumentationQuery::HookString{
|
|
"postGenerate", "preBuild", "postBuild",
|
|
"preCMakeBuild", "postCMakeBuild", "postTest",
|
|
"postInstall", "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 QueryHelper = EnumHelper<cmInstrumentationQuery::Query>(
|
|
cmInstrumentationQuery::QueryString, "query");
|
|
static auto const QueryListHelper =
|
|
JSONHelperBuilder::Vector<cmInstrumentationQuery::Query>(
|
|
ErrorMessages::InvalidArray, QueryHelper);
|
|
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("queries"_s, &QueryRoot::queries, 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<Query>& queries,
|
|
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.queries.begin(), this->queryRoot.queries.end(),
|
|
std::inserter(queries, queries.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;
|
|
}
|