summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-03-30 12:51:06 +0000
committerKitware Robot <kwrobot@kitware.com>2023-03-30 08:51:18 -0400
commit4901fdb201bc6264e976e105780a490d9c0eba19 (patch)
treea9f1ac305890acb723453d4145987555167395d2
parent1d1ee2b049ec3010d1740f276c8a3413ad4c76d3 (diff)
parent19305afd8a2a46925b1a880de68f7be0ad1f3091 (diff)
downloadcmake-4901fdb201bc6264e976e105780a490d9c0eba19.tar.gz
Merge topic 'presets-json-errors'
19305afd8a presets: Improve JSON parser and error messages Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Acked-by: scivision <michael@scivision.dev> Merge-request: !8290
-rw-r--r--Source/CMakeLists.txt3
-rw-r--r--Source/CPack/cpack.cxx7
-rw-r--r--Source/CTest/cmCTestResourceSpec.cxx148
-rw-r--r--Source/CTest/cmCTestResourceSpec.h59
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx6
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx7
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h3
-rw-r--r--Source/QtDialog/QCMake.cxx9
-rw-r--r--Source/QtDialog/QCMake.h7
-rw-r--r--Source/cmCMakePresetErrors.h242
-rw-r--r--Source/cmCMakePresetsGraph.cxx379
-rw-r--r--Source/cmCMakePresetsGraph.h92
-rw-r--r--Source/cmCMakePresetsGraphInternal.h69
-rw-r--r--Source/cmCMakePresetsGraphReadJSON.cxx426
-rw-r--r--Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx45
-rw-r--r--Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx93
-rw-r--r--Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx37
-rw-r--r--Source/cmCMakePresetsGraphReadJSONTestPresets.cxx161
-rw-r--r--Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx53
-rw-r--r--Source/cmCTest.cxx9
-rw-r--r--Source/cmJSONHelpers.h352
-rw-r--r--Source/cmJSONState.cxx163
-rw-r--r--Source/cmJSONState.h73
-rw-r--r--Source/cmake.cxx24
-rw-r--r--Tests/CMakeLib/testCTestResourceAllocator.cxx16
-rw-r--r--Tests/CMakeLib/testCTestResourceSpec.cxx115
-rw-r--r--Tests/CMakeLib/testJSONHelpers.cxx203
-rw-r--r--Tests/RunCMake/CMakePresets/Comment-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyCacheKey-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyEnvKey-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt8
-rw-r--r--Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt4
-rw-r--r--Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/FileDirFuture-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/HighVersion-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt4
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt6
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt7
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt4
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt10
-rw-r--r--Tests/RunCMake/CMakePresets/LowVersion-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt4
-rw-r--r--Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt4
-rw-r--r--Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt4
-rw-r--r--Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/NoVersion-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/PathListSepFuture-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsBuild/ConfigurePresetUnreachable-build-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-build-badConfigurePreset-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-configure-default-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsBuild/NoConfigurePreset-build-noConfigurePreset-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsBuild/PresetsUnsupported-build-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/ConfigurePresetUnreachable-test-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-configure-default-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-test-badConfigurePreset-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/NoConfigurePreset-test-noConfigurePreset-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/OutputJUnitUnsupported-test-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/PresetsUnsupported-test-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsTest/TestOutputTruncationUnsupported-test-x-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsWorkflow/ConfigureStepMismatch-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsWorkflow/NoWorkflowSteps-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt3
-rw-r--r--Tests/RunCMake/CMakePresetsWorkflow/UnsupportedVersion-stderr.txt3
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx3
114 files changed, 1930 insertions, 1213 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 33514ba1bf..3ae0bc643b 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -128,6 +128,7 @@ add_library(
cmCLocaleEnvironmentScope.cxx
cmCMakePath.h
cmCMakePath.cxx
+ cmCMakePresetErrors.h
cmCMakePresetsGraph.cxx
cmCMakePresetsGraph.h
cmCMakePresetsGraphInternal.h
@@ -319,6 +320,8 @@ add_library(
cmInstallDirectoryGenerator.h
cmInstallDirectoryGenerator.cxx
cmJSONHelpers.h
+ cmJSONState.cxx
+ cmJSONState.h
cmLDConfigLDConfigTool.cxx
cmLDConfigLDConfigTool.h
cmLDConfigTool.cxx
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 225711808c..234bc59352 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -28,6 +28,7 @@
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
+#include "cmJSONState.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -265,11 +266,11 @@ int main(int argc, char const* const* argv)
cmCMakePresetsGraph presetsGraph;
auto result = presetsGraph.ReadProjectPresets(workingDirectory);
- if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
+ if (result != true) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Could not read presets from "
- << workingDirectory << ": "
- << cmCMakePresetsGraph::ResultToString(result) << '\n');
+ << workingDirectory << ":"
+ << presetsGraph.parseState.GetErrorMessage() << '\n');
return 1;
}
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx
index 142b07de1a..0e81fa9423 100644
--- a/Source/CTest/cmCTestResourceSpec.cxx
+++ b/Source/CTest/cmCTestResourceSpec.cxx
@@ -10,17 +10,14 @@
#include <cmext/string_view>
-#include <cm3p/json/reader.h>
#include <cm3p/json/value.h>
-#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmJSONHelpers.h"
namespace {
-using JSONHelperBuilder =
- cmJSONHelperBuilder<cmCTestResourceSpec::ReadFileResult>;
+using JSONHelperBuilder = cmJSONHelperBuilder;
const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
@@ -36,165 +33,104 @@ struct TopVersion
};
auto const VersionFieldHelper =
- JSONHelperBuilder::Int(cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_VERSION);
+ JSONHelperBuilder::Int(cmCTestResourceSpecErrors::INVALID_VERSION);
auto const VersionHelper = JSONHelperBuilder::Required<Version>(
- cmCTestResourceSpec::ReadFileResult::NO_VERSION,
- JSONHelperBuilder::Object<Version>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_VERSION)
+ cmCTestResourceSpecErrors::NO_VERSION,
+ JSONHelperBuilder::Object<Version>()
.Bind("major"_s, &Version::Major, VersionFieldHelper)
.Bind("minor"_s, &Version::Minor, VersionFieldHelper));
-auto const RootVersionHelper =
- JSONHelperBuilder::Object<TopVersion>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
- .Bind("version"_s, &TopVersion::Version, VersionHelper, false);
+auto const RootVersionHelper = JSONHelperBuilder::Object<TopVersion>().Bind(
+ "version"_s, &TopVersion::Version, VersionHelper, false);
-cmCTestResourceSpec::ReadFileResult ResourceIdHelper(std::string& out,
- const Json::Value* value)
+bool ResourceIdHelper(std::string& out, const Json::Value* value,
+ cmJSONState* state)
{
- auto result = JSONHelperBuilder::String(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE)(out, value);
- if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
- return result;
+ if (!JSONHelperBuilder::String(cmCTestResourceSpecErrors::INVALID_RESOURCE)(
+ out, value, state)) {
+ return false;
}
cmsys::RegularExpressionMatch match;
if (!IdRegex.find(out.c_str(), match)) {
- return cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE;
+ cmCTestResourceSpecErrors::INVALID_RESOURCE(value, state);
+ return false;
}
- return cmCTestResourceSpec::ReadFileResult::READ_OK;
+ return true;
}
auto const ResourceHelper =
- JSONHelperBuilder::Object<cmCTestResourceSpec::Resource>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE)
+ JSONHelperBuilder::Object<cmCTestResourceSpec::Resource>()
.Bind("id"_s, &cmCTestResourceSpec::Resource::Id, ResourceIdHelper)
- .Bind("slots"_s, &cmCTestResourceSpec::Resource::Capacity,
- JSONHelperBuilder::UInt(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, 1),
- false);
+ .Bind(
+ "slots"_s, &cmCTestResourceSpec::Resource::Capacity,
+ JSONHelperBuilder::UInt(cmCTestResourceSpecErrors::INVALID_RESOURCE, 1),
+ false);
auto const ResourceListHelper =
JSONHelperBuilder::Vector<cmCTestResourceSpec::Resource>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE_TYPE,
- ResourceHelper);
+ cmCTestResourceSpecErrors::INVALID_RESOURCE_TYPE, ResourceHelper);
auto const ResourceMapHelper =
JSONHelperBuilder::MapFilter<std::vector<cmCTestResourceSpec::Resource>>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC,
- ResourceListHelper, [](const std::string& key) -> bool {
+ cmCTestResourceSpecErrors::INVALID_SOCKET_SPEC, ResourceListHelper,
+ [](const std::string& key) -> bool {
cmsys::RegularExpressionMatch match;
return IdentifierRegex.find(key.c_str(), match);
});
auto const SocketSetHelper = JSONHelperBuilder::Vector<
std::map<std::string, std::vector<cmCTestResourceSpec::Resource>>>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, ResourceMapHelper);
+ cmCTestResourceSpecErrors::INVALID_SOCKET_SPEC, ResourceMapHelper);
-cmCTestResourceSpec::ReadFileResult SocketHelper(
- cmCTestResourceSpec::Socket& out, const Json::Value* value)
+bool SocketHelper(cmCTestResourceSpec::Socket& out, const Json::Value* value,
+ cmJSONState* state)
{
std::vector<
std::map<std::string, std::vector<cmCTestResourceSpec::Resource>>>
sockets;
- cmCTestResourceSpec::ReadFileResult result = SocketSetHelper(sockets, value);
- if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
- return result;
+ if (!SocketSetHelper(sockets, value, state)) {
+ return false;
}
if (sockets.size() > 1) {
- return cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC;
+ cmCTestResourceSpecErrors::INVALID_SOCKET_SPEC(value, state);
+ return false;
}
if (sockets.empty()) {
out.Resources.clear();
} else {
out.Resources = std::move(sockets[0]);
}
- return cmCTestResourceSpec::ReadFileResult::READ_OK;
+ return true;
}
auto const LocalRequiredHelper =
JSONHelperBuilder::Required<cmCTestResourceSpec::Socket>(
- cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, SocketHelper);
+ cmCTestResourceSpecErrors::INVALID_SOCKET_SPEC, SocketHelper);
-auto const RootHelper = JSONHelperBuilder::Object<cmCTestResourceSpec>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
- .Bind("local", &cmCTestResourceSpec::LocalSocket,
- LocalRequiredHelper, false);
+auto const RootHelper = JSONHelperBuilder::Object<cmCTestResourceSpec>().Bind(
+ "local", &cmCTestResourceSpec::LocalSocket, LocalRequiredHelper, false);
}
-cmCTestResourceSpec::ReadFileResult cmCTestResourceSpec::ReadFromJSONFile(
- const std::string& filename)
+bool cmCTestResourceSpec::ReadFromJSONFile(const std::string& filename)
{
- cmsys::ifstream fin(filename.c_str());
- if (!fin) {
- return ReadFileResult::FILE_NOT_FOUND;
- }
-
Json::Value root;
- Json::CharReaderBuilder builder;
- if (!Json::parseFromStream(builder, fin, &root, nullptr)) {
- return ReadFileResult::JSON_PARSE_ERROR;
+
+ this->parseState = cmJSONState(filename, &root);
+ if (!this->parseState.errors.empty()) {
+ return false;
}
TopVersion version;
- ReadFileResult result;
- if ((result = RootVersionHelper(version, &root)) !=
- ReadFileResult::READ_OK) {
+ bool result;
+ if ((result = RootVersionHelper(version, &root, &parseState)) != true) {
return result;
}
if (version.Version.Major != 1 || version.Version.Minor != 0) {
- return ReadFileResult::UNSUPPORTED_VERSION;
+ return false;
}
- return RootHelper(*this, &root);
-}
-
-const char* cmCTestResourceSpec::ResultToString(ReadFileResult result)
-{
- switch (result) {
- case ReadFileResult::READ_OK:
- return "OK";
-
- case ReadFileResult::FILE_NOT_FOUND:
- return "File not found";
-
- case ReadFileResult::JSON_PARSE_ERROR:
- return "JSON parse error";
-
- case ReadFileResult::INVALID_ROOT:
- return "Invalid root object";
-
- case ReadFileResult::NO_VERSION:
- return "No version specified";
-
- case ReadFileResult::INVALID_VERSION:
- return "Invalid version object";
-
- case ReadFileResult::UNSUPPORTED_VERSION:
- return "Unsupported version";
-
- case ReadFileResult::INVALID_SOCKET_SPEC:
- return "Invalid socket object";
-
- case ReadFileResult::INVALID_RESOURCE_TYPE:
- return "Invalid resource type object";
-
- case ReadFileResult::INVALID_RESOURCE:
- return "Invalid resource object";
-
- default:
- return "Unknown";
- }
+ return RootHelper(*this, &root, &parseState);
}
bool cmCTestResourceSpec::operator==(const cmCTestResourceSpec& other) const
diff --git a/Source/CTest/cmCTestResourceSpec.h b/Source/CTest/cmCTestResourceSpec.h
index 72628a346a..37ccd72fee 100644
--- a/Source/CTest/cmCTestResourceSpec.h
+++ b/Source/CTest/cmCTestResourceSpec.h
@@ -8,6 +8,12 @@
#include <string>
#include <vector>
+#include "cmJSONState.h"
+
+namespace Json {
+class Value;
+}
+
class cmCTestResourceSpec
{
public:
@@ -31,24 +37,45 @@ public:
};
Socket LocalSocket;
+ cmJSONState parseState;
- enum class ReadFileResult
- {
- READ_OK,
- FILE_NOT_FOUND,
- JSON_PARSE_ERROR,
- INVALID_ROOT,
- NO_VERSION,
- INVALID_VERSION,
- UNSUPPORTED_VERSION,
- INVALID_SOCKET_SPEC, // Can't be INVALID_SOCKET due to a Windows macro
- INVALID_RESOURCE_TYPE,
- INVALID_RESOURCE,
- };
-
- ReadFileResult ReadFromJSONFile(const std::string& filename);
- static const char* ResultToString(ReadFileResult result);
+ bool ReadFromJSONFile(const std::string& filename);
bool operator==(const cmCTestResourceSpec& other) const;
bool operator!=(const cmCTestResourceSpec& other) const;
};
+
+namespace cmCTestResourceSpecErrors {
+const auto FILE_NOT_FOUND = [](const Json::Value*, cmJSONState* state) {
+ state->AddError("File not found");
+};
+const auto JSON_PARSE_ERROR = [](const Json::Value* value,
+ cmJSONState* state) {
+ state->AddErrorAtValue("JSON parse error", value);
+};
+const auto INVALID_ROOT = [](const Json::Value* value, cmJSONState* state) {
+ state->AddErrorAtValue("Invalid root object", value);
+};
+const auto NO_VERSION = [](const Json::Value* value, cmJSONState* state) {
+ state->AddErrorAtValue("No version specified", value);
+};
+const auto INVALID_VERSION = [](const Json::Value* value, cmJSONState* state) {
+ state->AddErrorAtValue("Invalid version object", value);
+};
+const auto UNSUPPORTED_VERSION = [](const Json::Value* value,
+ cmJSONState* state) {
+ state->AddErrorAtValue("Unsupported version", value);
+};
+const auto INVALID_SOCKET_SPEC = [](const Json::Value* value,
+ cmJSONState* state) {
+ state->AddErrorAtValue("Invalid socket object", value);
+};
+const auto INVALID_RESOURCE_TYPE = [](const Json::Value* value,
+ cmJSONState* state) {
+ state->AddErrorAtValue("Invalid resource type object", value);
+};
+const auto INVALID_RESOURCE = [](const Json::Value* value,
+ cmJSONState* state) {
+ state->AddErrorAtValue("Invalid resource object", value);
+};
+}
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 1d509cfc33..f693ace4b5 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -37,6 +37,7 @@
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmJSONState.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -1346,12 +1347,11 @@ bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
}
if (!this->ResourceSpecFile.empty()) {
this->UseResourceSpec = true;
- auto result = this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile);
- if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
+ if (!this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Could not read/parse resource spec file "
<< this->ResourceSpecFile << ": "
- << cmCTestResourceSpec::ResultToString(result)
+ << this->ResourceSpec.parseState.GetErrorMessage()
<< std::endl);
return false;
}
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 1effdd3cb1..ab778183a3 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -732,13 +732,12 @@ void CMakeSetupDialog::updatePreset(const QString& name)
}
}
-void CMakeSetupDialog::showPresetLoadError(
- const QString& dir, cmCMakePresetsGraph::ReadFileResult result)
+void CMakeSetupDialog::showPresetLoadError(const QString& dir,
+ const QString& message)
{
QMessageBox::warning(
this, "Error Reading CMake Presets",
- QString("Could not read presets from %1: %2")
- .arg(dir, cmCMakePresetsGraph::ResultToString(result)));
+ QString("Could not read presets from %1: %2").arg(dir, message));
}
void CMakeSetupDialog::doBinaryBrowse()
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 8aee70de3c..d4c72cb17b 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -59,8 +59,7 @@ protected slots:
void updateBinaryDirectory(const QString& dir);
void updatePresets(const QVector<QCMakePreset>& presets);
void updatePreset(const QString& name);
- void showPresetLoadError(const QString& dir,
- cmCMakePresetsGraph::ReadFileResult result);
+ void showPresetLoadError(const QString& dir, const QString& message);
void showProgress(const QString& msg, float percent);
void setEnabledState(bool);
bool setupFirstConfigure();
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index ea02f98d54..6ed24ca501 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -33,7 +33,6 @@ QCMake::QCMake(QObject* p)
qRegisterMetaType<QCMakePropertyList>();
qRegisterMetaType<QProcessEnvironment>();
qRegisterMetaType<QVector<QCMakePreset>>();
- qRegisterMetaType<cmCMakePresetsGraph::ReadFileResult>();
cmSystemTools::DisableRunCommandOutput();
cmSystemTools::SetRunCommandHideConsole(true);
@@ -530,9 +529,11 @@ void QCMake::loadPresets()
{
auto result = this->CMakePresetsGraph.ReadProjectPresets(
this->SourceDirectory.toStdString(), true);
- if (result != this->LastLoadPresetsResult &&
- result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
- emit this->presetLoadError(this->SourceDirectory, result);
+ if (result != this->LastLoadPresetsResult && !result) {
+ emit this->presetLoadError(
+ this->SourceDirectory,
+ QString::fromStdString(
+ this->CMakePresetsGraph.parseState.GetErrorMessage(false)));
}
this->LastLoadPresetsResult = result;
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index 8a7e4cb8aa..0890558127 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -60,7 +60,6 @@ using QCMakePropertyList = QList<QCMakeProperty>;
Q_DECLARE_METATYPE(QCMakeProperty)
Q_DECLARE_METATYPE(QCMakePropertyList)
Q_DECLARE_METATYPE(QProcessEnvironment)
-Q_DECLARE_METATYPE(cmCMakePresetsGraph::ReadFileResult)
/// Qt API for CMake library.
/// Wrapper like class allows for easier integration with
@@ -158,8 +157,7 @@ signals:
/// signal when the selected preset changes
void presetChanged(const QString& name);
/// signal when there's an error reading the presets files
- void presetLoadError(const QString& dir,
- cmCMakePresetsGraph::ReadFileResult error);
+ void presetLoadError(const QString& dir, const QString& error);
/// signal when uninitialized warning changes
void warnUninitializedModeChanged(bool value);
/// signal for progress events
@@ -203,8 +201,7 @@ protected:
QString Toolset;
std::vector<cmake::GeneratorInfo> AvailableGenerators;
cmCMakePresetsGraph CMakePresetsGraph;
- cmCMakePresetsGraph::ReadFileResult LastLoadPresetsResult =
- cmCMakePresetsGraph::ReadFileResult::READ_OK;
+ bool LastLoadPresetsResult = true;
QString PresetName;
QString CMakeExecutable;
QAtomicInt InterruptFlag;
diff --git a/Source/cmCMakePresetErrors.h b/Source/cmCMakePresetErrors.h
new file mode 100644
index 0000000000..c669cb1fdf
--- /dev/null
+++ b/Source/cmCMakePresetErrors.h
@@ -0,0 +1,242 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <cm3p/json/value.h>
+
+#include "cmJSONHelpers.h"
+#include "cmJSONState.h"
+#include "cmStringAlgorithms.h"
+
+namespace cmCMakePresetErrors {
+const auto getPreset = [](cmJSONState* state) -> const Json::Value* {
+ if (state->parseStack.size() < 2) {
+ return nullptr;
+ }
+ std::string firstKey = state->parseStack[0].first;
+ if (firstKey == "configurePresets" || firstKey == "packagePresets" ||
+ firstKey == "buildPresets" || firstKey == "testPresets") {
+ return state->parseStack[1].second;
+ }
+ return nullptr;
+};
+const auto getPresetName = [](cmJSONState* state) -> std::string {
+#if !defined(CMAKE_BOOTSTRAP)
+ const Json::Value* preset = getPreset(state);
+ if (preset != nullptr && preset->isMember("name")) {
+ return preset->operator[]("name").asString();
+ }
+#endif
+ return "";
+};
+const auto getVariableName = [](cmJSONState* state) -> std::string {
+ std::string var = state->key_after("cacheVariables");
+ std::string errMsg = cmStrCat("variable \"", var, "\"");
+ errMsg = cmStrCat(errMsg, " for preset \"", getPresetName(state), "\"");
+ return errMsg;
+};
+const auto FILE_NOT_FOUND = [](const std::string& filename,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("File not found: ", filename));
+};
+const auto INVALID_ROOT = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue("Invalid root object", value);
+};
+const auto NO_VERSION = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue("No \"version\" field", value);
+};
+const auto INVALID_VERSION = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue("Invalid \"version\" field", value);
+};
+const auto UNRECOGNIZED_VERSION = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue("Unrecognized \"version\" field", value);
+};
+const auto INVALID_PRESETS = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue("Invalid \"configurePresets\" field", value);
+};
+const auto INVALID_PRESET = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue("Invalid preset", value);
+};
+const auto INVALID_PRESET_NAMED = [](const std::string& presetName,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Invalid preset: \"", presetName, "\""));
+};
+const auto INVALID_VARIABLE = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ std::string var = cmCMakePresetErrors::getVariableName(state);
+ state->AddErrorAtValue(cmStrCat("Invalid CMake ", var), value);
+};
+const auto DUPLICATE_PRESETS = [](const std::string& presetName,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Duplicate preset: \"", presetName, "\""));
+};
+const auto CYCLIC_PRESET_INHERITANCE = [](const std::string& presetName,
+ cmJSONState* state) -> void {
+ state->AddError(
+ cmStrCat("Cyclic preset inheritance for preset \"", presetName, "\""));
+};
+const auto INHERITED_PRESET_UNREACHABLE_FROM_FILE =
+ [](const std::string& presetName, cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Inherited preset \"", presetName,
+ "\" is unreachable from preset's file"));
+};
+const auto CONFIGURE_PRESET_UNREACHABLE_FROM_FILE =
+ [](const std::string& presetName, cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Configure preset \"", presetName,
+ "\" is unreachable from preset's file"));
+};
+const auto INVALID_MACRO_EXPANSION = [](const std::string& presetName,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, "\""));
+};
+const auto BUILD_TEST_PRESETS_UNSUPPORTED = [](const Json::Value*,
+ cmJSONState* state) -> void {
+ state->AddError("File version must be 2 or higher for build and test preset "
+ "support");
+};
+const auto PACKAGE_PRESETS_UNSUPPORTED = [](const Json::Value*,
+ cmJSONState* state) -> void {
+ state->AddError(
+ "File version must be 6 or higher for package preset support");
+};
+const auto WORKFLOW_PRESETS_UNSUPPORTED = [](const Json::Value*,
+ cmJSONState* state) -> void {
+ state->AddError(
+ "File version must be 6 or higher for workflow preset support");
+};
+const auto INCLUDE_UNSUPPORTED = [](const Json::Value*,
+ cmJSONState* state) -> void {
+ state->AddError("File version must be 4 or higher for include support");
+};
+const auto INVALID_INCLUDE = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue("Invalid \"include\" field", value);
+};
+const auto INVALID_CONFIGURE_PRESET = [](const std::string& presetName,
+ cmJSONState* state) -> void {
+ state->AddError(
+ cmStrCat(R"(Invalid "configurePreset": ")", presetName, "\""));
+};
+const auto INSTALL_PREFIX_UNSUPPORTED = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue(
+ "File version must be 3 or higher for installDir preset "
+ "support",
+ value);
+};
+const auto CONDITION_UNSUPPORTED = [](cmJSONState* state) -> void {
+ state->AddError("File version must be 3 or higher for condition support");
+};
+const auto TOOLCHAIN_FILE_UNSUPPORTED = [](cmJSONState* state) -> void {
+ state->AddError("File version must be 3 or higher for toolchainFile preset "
+ "support");
+};
+const auto CYCLIC_INCLUDE = [](const std::string& file,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Cyclic include among preset files: ", file));
+};
+const auto TEST_OUTPUT_TRUNCATION_UNSUPPORTED =
+ [](cmJSONState* state) -> void {
+ state->AddError("File version must be 5 or higher for testOutputTruncation "
+ "preset support");
+};
+const auto INVALID_WORKFLOW_STEPS = [](const std::string& workflowStep,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, "\""));
+};
+const auto NO_WORKFLOW_STEPS = [](const std::string& presetName,
+ cmJSONState* state) -> void {
+ state->AddError(
+ cmStrCat("No workflow steps specified for \"", presetName, "\""));
+};
+const auto FIRST_WORKFLOW_STEP_NOT_CONFIGURE = [](const std::string& stepName,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("First workflow step \"", stepName,
+ "\" must be a configure step"));
+};
+const auto CONFIGURE_WORKFLOW_STEP_NOT_FIRST = [](const std::string& stepName,
+ cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Configure workflow step \"", stepName,
+ "\" must be the first step"));
+};
+const auto WORKFLOW_STEP_UNREACHABLE_FROM_FILE =
+ [](const std::string& workflowStep, cmJSONState* state) -> void {
+ state->AddError(cmStrCat("Workflow step \"", workflowStep,
+ "\" is unreachable from preset's file"));
+};
+const auto CTEST_JUNIT_UNSUPPORTED = [](cmJSONState* state) -> void {
+ state->AddError(
+ "File version must be 6 or higher for CTest JUnit output support");
+};
+const auto UNRECOGNIZED_CMAKE_VERSION = [](const std::string& version,
+ int current, int required) {
+ return [version, current, required](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue(cmStrCat("\"cmakeMinimumRequired\" ", version,
+ " version ", required,
+ " must be less than ", current),
+ value);
+ };
+};
+const auto INVALID_PRESET_NAME = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ std::string errMsg = "Invalid Preset Name";
+ if (value && value->isConvertibleTo(Json::ValueType::stringValue) &&
+ !value->asString().empty()) {
+ errMsg = cmStrCat(errMsg, ": ", value->asString());
+ }
+ state->AddErrorAtValue(errMsg, value);
+};
+const auto INVALID_CONDITION = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ state->AddErrorAtValue(
+ cmStrCat("Invalid condition for preset \"", getPresetName(state), "\""),
+ value);
+};
+const auto INVALID_CONDITION_OBJECT =
+ [](JsonErrors::ObjectError errorType,
+ const Json::Value::Members& extraFields) {
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState* state) -> std::string {
+ return cmStrCat(" condition for preset \"", getPresetName(state),
+ "\"");
+ })(errorType, extraFields);
+ };
+const auto INVALID_VARIABLE_OBJECT =
+ [](JsonErrors::ObjectError errorType,
+ const Json::Value::Members& extraFields) {
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState* state) -> std::string {
+ return getVariableName(state);
+ })(errorType, extraFields);
+ };
+const auto INVALID_PRESET_OBJECT =
+ [](JsonErrors::ObjectError errorType,
+ const Json::Value::Members& extraFields) {
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState*) -> std::string {
+ return "Preset";
+ })(errorType, extraFields);
+ };
+const auto INVALID_ROOT_OBJECT = [](JsonErrors::ObjectError errorType,
+ const Json::Value::Members& extraFields) {
+ return JsonErrors::INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState*) -> std::string {
+ return "root object";
+ })(errorType, extraFields);
+};
+const auto PRESET_MISSING_FIELD = [](const std::string& presetName,
+ const std::string& missingField,
+ cmJSONState* state) {
+ state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
+ missingField, "\""));
+};
+}
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index 7325e447df..13e8bad1f1 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -14,6 +14,7 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmCMakePresetErrors.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -39,7 +40,6 @@ enum class CycleStatus
Verified,
};
-using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
using TestPreset = cmCMakePresetsGraph::TestPreset;
@@ -81,17 +81,18 @@ void InheritVector(std::vector<T>& child, const std::vector<T>& parent)
* inheritance.
*/
template <class T>
-ReadFileResult VisitPreset(
+bool VisitPreset(
T& preset,
std::map<std::string, cmCMakePresetsGraph::PresetPair<T>>& presets,
- std::map<std::string, CycleStatus> cycleStatus,
- const cmCMakePresetsGraph& graph)
+ std::map<std::string, CycleStatus> cycleStatus, cmCMakePresetsGraph& graph)
{
switch (cycleStatus[preset.Name]) {
case CycleStatus::InProgress:
- return ReadFileResult::CYCLIC_PRESET_INHERITANCE;
+ cmCMakePresetErrors::CYCLIC_PRESET_INHERITANCE(preset.Name,
+ &graph.parseState);
+ return false;
case CycleStatus::Verified:
- return ReadFileResult::READ_OK;
+ return true;
default:
break;
}
@@ -99,28 +100,41 @@ ReadFileResult VisitPreset(
cycleStatus[preset.Name] = CycleStatus::InProgress;
if (preset.Environment.count("") != 0) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
+ return false;
}
- CHECK_OK(preset.VisitPresetBeforeInherit());
+ bool result = preset.VisitPresetBeforeInherit();
+ if (!result) {
+ cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
+ return false;
+ }
for (auto const& i : preset.Inherits) {
auto parent = presets.find(i);
if (parent == presets.end()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
+ return false;
}
auto& parentPreset = parent->second.Unexpanded;
if (!preset.OriginFile->ReachableFiles.count(parentPreset.OriginFile)) {
- return ReadFileResult::INHERITED_PRESET_UNREACHABLE_FROM_FILE;
+ cmCMakePresetErrors::INHERITED_PRESET_UNREACHABLE_FROM_FILE(
+ preset.Name, &graph.parseState);
+ return false;
}
- auto result = VisitPreset(parentPreset, presets, cycleStatus, graph);
- if (result != ReadFileResult::READ_OK) {
- return result;
+ if (!VisitPreset(parentPreset, presets, cycleStatus, graph)) {
+ return false;
}
- CHECK_OK(preset.VisitPresetInherit(parentPreset));
+ result = preset.VisitPresetInherit(parentPreset);
+ if (!result) {
+ cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
+ return false;
+ }
for (auto const& v : parentPreset.Environment) {
preset.Environment.insert(v);
@@ -135,16 +149,21 @@ ReadFileResult VisitPreset(
preset.ConditionEvaluator.reset();
}
- CHECK_OK(preset.VisitPresetAfterInherit(graph.GetVersion(preset)));
+ result = preset.VisitPresetAfterInherit(graph.GetVersion(preset),
+ &graph.parseState);
+ if (!result) {
+ cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name, &graph.parseState);
+ return false;
+ }
cycleStatus[preset.Name] = CycleStatus::Verified;
- return ReadFileResult::READ_OK;
+ return true;
}
template <class T>
-ReadFileResult ComputePresetInheritance(
+bool ComputePresetInheritance(
std::map<std::string, cmCMakePresetsGraph::PresetPair<T>>& presets,
- const cmCMakePresetsGraph& graph)
+ cmCMakePresetsGraph& graph)
{
std::map<std::string, CycleStatus> cycleStatus;
for (auto const& it : presets) {
@@ -153,13 +172,12 @@ ReadFileResult ComputePresetInheritance(
for (auto& it : presets) {
auto& preset = it.second.Unexpanded;
- auto result = VisitPreset<T>(preset, presets, cycleStatus, graph);
- if (result != ReadFileResult::READ_OK) {
- return result;
+ if (!VisitPreset<T>(preset, presets, cycleStatus, graph)) {
+ return false;
}
}
- return ReadFileResult::READ_OK;
+ return true;
}
constexpr const char* ValidPrefixes[] = {
@@ -338,7 +356,7 @@ bool ExpandMacros(const cmCMakePresetsGraph& /*graph*/,
}
template <class T>
-bool ExpandMacros(const cmCMakePresetsGraph& graph, const T& preset,
+bool ExpandMacros(cmCMakePresetsGraph& graph, const T& preset,
cm::optional<T>& out)
{
out.emplace(preset);
@@ -448,6 +466,8 @@ bool ExpandMacros(const cmCMakePresetsGraph& graph, const T& preset,
switch (VisitEnv(*v.second, envCycles[v.first], macroExpanders,
graph.GetVersion(preset))) {
case ExpandMacroResult::Error:
+ cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
return false;
case ExpandMacroResult::Ignore:
out.reset();
@@ -462,6 +482,8 @@ bool ExpandMacros(const cmCMakePresetsGraph& graph, const T& preset,
cm::optional<bool> result;
if (!preset.ConditionEvaluator->Evaluate(
macroExpanders, graph.GetVersion(preset), result)) {
+ cmCMakePresetErrors::INVALID_PRESET_NAMED(preset.Name,
+ &graph.parseState);
return false;
}
if (!result) {
@@ -594,39 +616,44 @@ ExpandMacroResult ExpandMacro(std::string& out,
}
template <typename T>
-ReadFileResult SetupWorkflowConfigurePreset(
- const T& preset, const ConfigurePreset*& configurePreset)
+bool SetupWorkflowConfigurePreset(const T& preset,
+ const ConfigurePreset*& configurePreset,
+ cmJSONState* state)
{
if (preset.ConfigurePreset != configurePreset->Name) {
- return ReadFileResult::INVALID_WORKFLOW_STEPS;
+ cmCMakePresetErrors::INVALID_WORKFLOW_STEPS(configurePreset->Name, state);
+ return false;
}
- return ReadFileResult::READ_OK;
+ return true;
}
template <>
-ReadFileResult SetupWorkflowConfigurePreset<ConfigurePreset>(
- const ConfigurePreset& preset, const ConfigurePreset*& configurePreset)
+bool SetupWorkflowConfigurePreset<ConfigurePreset>(
+ const ConfigurePreset& preset, const ConfigurePreset*& configurePreset,
+ cmJSONState*)
{
configurePreset = &preset;
- return ReadFileResult::READ_OK;
+ return true;
}
template <typename T>
-ReadFileResult TryReachPresetFromWorkflow(
+bool TryReachPresetFromWorkflow(
const WorkflowPreset& origin,
const std::map<std::string, PresetPair<T>>& presets, const std::string& name,
- const ConfigurePreset*& configurePreset)
+ const ConfigurePreset*& configurePreset, cmJSONState* state)
{
auto it = presets.find(name);
if (it == presets.end()) {
- return ReadFileResult::INVALID_WORKFLOW_STEPS;
+ cmCMakePresetErrors::INVALID_WORKFLOW_STEPS(name, state);
+ return false;
}
if (!origin.OriginFile->ReachableFiles.count(
it->second.Unexpanded.OriginFile)) {
- return ReadFileResult::WORKFLOW_STEP_UNREACHABLE_FROM_FILE;
+ cmCMakePresetErrors::WORKFLOW_STEP_UNREACHABLE_FROM_FILE(name, state);
+ return false;
}
return SetupWorkflowConfigurePreset<T>(it->second.Unexpanded,
- configurePreset);
+ configurePreset, state);
}
}
@@ -722,8 +749,7 @@ bool cmCMakePresetsGraphInternal::NotCondition::Evaluate(
return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::ConfigurePreset::VisitPresetInherit(
+bool cmCMakePresetsGraph::ConfigurePreset::VisitPresetInherit(
const cmCMakePresetsGraph::Preset& parentPreset)
{
auto& preset = *this;
@@ -753,50 +779,52 @@ cmCMakePresetsGraph::ConfigurePreset::VisitPresetInherit(
preset.CacheVariables.insert(v);
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::ConfigurePreset::VisitPresetBeforeInherit()
+bool cmCMakePresetsGraph::ConfigurePreset::VisitPresetBeforeInherit()
{
auto& preset = *this;
if (preset.Environment.count("") != 0) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::ConfigurePreset::VisitPresetAfterInherit(int version)
+bool cmCMakePresetsGraph::ConfigurePreset::VisitPresetAfterInherit(
+ int version, cmJSONState* state)
{
auto& preset = *this;
if (!preset.Hidden) {
if (version < 3) {
if (preset.Generator.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::PRESET_MISSING_FIELD(preset.Name, "generator",
+ state);
+ return false;
}
if (preset.BinaryDir.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::PRESET_MISSING_FIELD(preset.Name, "binaryDir",
+ state);
+ return false;
}
}
if (preset.WarnDev == false && preset.ErrorDev == true) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
if (preset.WarnDeprecated == false && preset.ErrorDeprecated == true) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
if (preset.CacheVariables.count("") != 0) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::BuildPreset::VisitPresetInherit(
+bool cmCMakePresetsGraph::BuildPreset::VisitPresetInherit(
const cmCMakePresetsGraph::Preset& parentPreset)
{
auto& preset = *this;
@@ -815,21 +843,20 @@ cmCMakePresetsGraph::BuildPreset::VisitPresetInherit(
preset.ResolvePackageReferences = parent.ResolvePackageReferences;
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::BuildPreset::VisitPresetAfterInherit(int /* version */)
+bool cmCMakePresetsGraph::BuildPreset::VisitPresetAfterInherit(
+ int /* version */, cmJSONState* /*stat*/)
{
auto& preset = *this;
if (!preset.Hidden && preset.ConfigurePreset.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::TestPreset::VisitPresetInherit(
+bool cmCMakePresetsGraph::TestPreset::VisitPresetInherit(
const cmCMakePresetsGraph::Preset& parentPreset)
{
auto& preset = *this;
@@ -928,21 +955,20 @@ cmCMakePresetsGraph::TestPreset::VisitPresetInherit(
}
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::TestPreset::VisitPresetAfterInherit(int /* version */)
+bool cmCMakePresetsGraph::TestPreset::VisitPresetAfterInherit(
+ int /* version */, cmJSONState* /*state*/)
{
auto& preset = *this;
if (!preset.Hidden && preset.ConfigurePreset.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::PackagePreset::VisitPresetInherit(
+bool cmCMakePresetsGraph::PackagePreset::VisitPresetInherit(
const cmCMakePresetsGraph::Preset& parentPreset)
{
auto& preset = *this;
@@ -966,30 +992,29 @@ cmCMakePresetsGraph::PackagePreset::VisitPresetInherit(
InheritString(preset.PackageDirectory, parent.PackageDirectory);
InheritString(preset.VendorName, parent.VendorName);
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::PackagePreset::VisitPresetAfterInherit(int /* version */)
+bool cmCMakePresetsGraph::PackagePreset::VisitPresetAfterInherit(
+ int /* version */, cmJSONState* /*state*/)
{
auto& preset = *this;
if (!preset.Hidden && preset.ConfigurePreset.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::WorkflowPreset::VisitPresetInherit(
+bool cmCMakePresetsGraph::WorkflowPreset::VisitPresetInherit(
const cmCMakePresetsGraph::Preset& /*parentPreset*/)
{
- return ReadFileResult::READ_OK;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::WorkflowPreset::VisitPresetAfterInherit(int /* version */)
+bool cmCMakePresetsGraph::WorkflowPreset::VisitPresetAfterInherit(
+ int /* version */, cmJSONState* /*state*/)
{
- return ReadFileResult::READ_OK;
+ return true;
}
std::string cmCMakePresetsGraph::GetFilename(const std::string& sourceDir)
@@ -1002,22 +1027,21 @@ std::string cmCMakePresetsGraph::GetUserFilename(const std::string& sourceDir)
return cmStrCat(sourceDir, "/CMakeUserPresets.json");
}
-cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadProjectPresets(
- const std::string& sourceDir, bool allowNoFiles)
+bool cmCMakePresetsGraph::ReadProjectPresets(const std::string& sourceDir,
+ bool allowNoFiles)
{
this->SourceDir = sourceDir;
this->ClearPresets();
- auto result = this->ReadProjectPresetsInternal(allowNoFiles);
- if (result != ReadFileResult::READ_OK) {
+ if (!this->ReadProjectPresetsInternal(allowNoFiles)) {
this->ClearPresets();
+ return false;
}
- return result;
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult
-cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
+bool cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
{
bool haveOneFile = false;
@@ -1025,21 +1049,17 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
std::string filename = GetUserFilename(this->SourceDir);
std::vector<File*> inProgressFiles;
if (cmSystemTools::FileExists(filename)) {
- auto result =
- this->ReadJSONFile(filename, RootType::User, ReadReason::Root,
- inProgressFiles, file, this->errors);
- if (result != ReadFileResult::READ_OK) {
- return result;
+ if (!this->ReadJSONFile(filename, RootType::User, ReadReason::Root,
+ inProgressFiles, file, this->errors)) {
+ return false;
}
haveOneFile = true;
} else {
filename = GetFilename(this->SourceDir);
if (cmSystemTools::FileExists(filename)) {
- auto result =
- this->ReadJSONFile(filename, RootType::Project, ReadReason::Root,
- inProgressFiles, file, this->errors);
- if (result != ReadFileResult::READ_OK) {
- return result;
+ if (!this->ReadJSONFile(filename, RootType::Project, ReadReason::Root,
+ inProgressFiles, file, this->errors)) {
+ return false;
}
haveOneFile = true;
}
@@ -1047,19 +1067,28 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
assert(inProgressFiles.empty());
if (!haveOneFile) {
- return allowNoFiles ? ReadFileResult::READ_OK
- : ReadFileResult::FILE_NOT_FOUND;
+ if (allowNoFiles) {
+ return true;
+ }
+ cmCMakePresetErrors::FILE_NOT_FOUND(filename, &this->parseState);
+ return false;
}
- CHECK_OK(ComputePresetInheritance(this->ConfigurePresets, *this));
- CHECK_OK(ComputePresetInheritance(this->BuildPresets, *this));
- CHECK_OK(ComputePresetInheritance(this->TestPresets, *this));
- CHECK_OK(ComputePresetInheritance(this->PackagePresets, *this));
- CHECK_OK(ComputePresetInheritance(this->WorkflowPresets, *this));
+ bool result = ComputePresetInheritance(this->ConfigurePresets, *this) &&
+ ComputePresetInheritance(this->ConfigurePresets, *this) &&
+ ComputePresetInheritance(this->BuildPresets, *this) &&
+ ComputePresetInheritance(this->TestPresets, *this) &&
+ ComputePresetInheritance(this->PackagePresets, *this) &&
+ ComputePresetInheritance(this->WorkflowPresets, *this);
+ if (!result) {
+ return false;
+ }
for (auto& it : this->ConfigurePresets) {
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- return ReadFileResult::INVALID_MACRO_EXPANSION;
+ cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
+ return false;
}
}
@@ -1068,11 +1097,15 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const auto configurePreset =
this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
if (configurePreset == this->ConfigurePresets.end()) {
- return ReadFileResult::INVALID_CONFIGURE_PRESET;
+ cmCMakePresetErrors::INVALID_CONFIGURE_PRESET(it.first,
+ &this->parseState);
+ return false;
}
if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
configurePreset->second.Unexpanded.OriginFile)) {
- return ReadFileResult::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE;
+ cmCMakePresetErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
+ it.first, &this->parseState);
+ return false;
}
if (it.second.Unexpanded.InheritConfigureEnvironment.value_or(true)) {
@@ -1083,7 +1116,9 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- return ReadFileResult::INVALID_MACRO_EXPANSION;
+ cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
+ return false;
}
}
@@ -1092,11 +1127,15 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const auto configurePreset =
this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
if (configurePreset == this->ConfigurePresets.end()) {
- return ReadFileResult::INVALID_CONFIGURE_PRESET;
+ cmCMakePresetErrors::INVALID_CONFIGURE_PRESET(it.first,
+ &this->parseState);
+ return false;
}
if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
configurePreset->second.Unexpanded.OriginFile)) {
- return ReadFileResult::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE;
+ cmCMakePresetErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
+ it.first, &this->parseState);
+ return false;
}
if (it.second.Unexpanded.InheritConfigureEnvironment.value_or(true)) {
@@ -1107,7 +1146,9 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- return ReadFileResult::INVALID_MACRO_EXPANSION;
+ cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
+ return false;
}
}
@@ -1116,11 +1157,15 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const auto configurePreset =
this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
if (configurePreset == this->ConfigurePresets.end()) {
- return ReadFileResult::INVALID_CONFIGURE_PRESET;
+ cmCMakePresetErrors::INVALID_CONFIGURE_PRESET(it.first,
+ &this->parseState);
+ return false;
}
if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
configurePreset->second.Unexpanded.OriginFile)) {
- return ReadFileResult::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE;
+ cmCMakePresetErrors::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(
+ it.first, &this->parseState);
+ return false;
}
if (it.second.Unexpanded.InheritConfigureEnvironment.value_or(true)) {
@@ -1131,7 +1176,9 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- return ReadFileResult::INVALID_MACRO_EXPANSION;
+ cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
+ return false;
}
}
@@ -1141,126 +1188,56 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
const ConfigurePreset* configurePreset = nullptr;
for (auto const& step : it.second.Unexpanded.Steps) {
if (configurePreset == nullptr && step.PresetType != Type::Configure) {
- return ReadFileResult::INVALID_WORKFLOW_STEPS;
+ cmCMakePresetErrors::FIRST_WORKFLOW_STEP_NOT_CONFIGURE(
+ step.PresetName, &this->parseState);
+ return false;
}
if (configurePreset != nullptr && step.PresetType == Type::Configure) {
- return ReadFileResult::INVALID_WORKFLOW_STEPS;
+ cmCMakePresetErrors::CONFIGURE_WORKFLOW_STEP_NOT_FIRST(
+ step.PresetName, &this->parseState);
+ return false;
}
- ReadFileResult result;
switch (step.PresetType) {
case Type::Configure:
result = TryReachPresetFromWorkflow(
it.second.Unexpanded, this->ConfigurePresets, step.PresetName,
- configurePreset);
+ configurePreset, &this->parseState);
break;
case Type::Build:
result = TryReachPresetFromWorkflow(
it.second.Unexpanded, this->BuildPresets, step.PresetName,
- configurePreset);
+ configurePreset, &this->parseState);
break;
case Type::Test:
- result =
- TryReachPresetFromWorkflow(it.second.Unexpanded, this->TestPresets,
- step.PresetName, configurePreset);
+ result = TryReachPresetFromWorkflow(
+ it.second.Unexpanded, this->TestPresets, step.PresetName,
+ configurePreset, &this->parseState);
break;
case Type::Package:
result = TryReachPresetFromWorkflow(
it.second.Unexpanded, this->PackagePresets, step.PresetName,
- configurePreset);
+ configurePreset, &this->parseState);
break;
}
- if (result != ReadFileResult::READ_OK) {
- return result;
+ if (!result) {
+ return false;
}
}
if (configurePreset == nullptr) {
- return ReadFileResult::INVALID_WORKFLOW_STEPS;
+ cmCMakePresetErrors::NO_WORKFLOW_STEPS(it.first, &this->parseState);
+ return false;
}
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
- return ReadFileResult::INVALID_MACRO_EXPANSION;
+ cmCMakePresetErrors::INVALID_MACRO_EXPANSION(it.first,
+ &this->parseState);
+ return false;
}
}
- return ReadFileResult::READ_OK;
-}
-
-const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result)
-{
- switch (result) {
- case ReadFileResult::READ_OK:
- return "OK";
- case ReadFileResult::FILE_NOT_FOUND:
- return "File not found";
- case ReadFileResult::JSON_PARSE_ERROR:
- return "JSON parse error";
- case ReadFileResult::INVALID_ROOT:
- return "Invalid root object";
- case ReadFileResult::NO_VERSION:
- return "No \"version\" field";
- case ReadFileResult::INVALID_VERSION:
- return "Invalid \"version\" field";
- case ReadFileResult::UNRECOGNIZED_VERSION:
- return "Unrecognized \"version\" field";
- case ReadFileResult::INVALID_CMAKE_VERSION:
- return "Invalid \"cmakeMinimumRequired\" field";
- case ReadFileResult::UNRECOGNIZED_CMAKE_VERSION:
- return "\"cmakeMinimumRequired\" version too new";
- case ReadFileResult::INVALID_PRESETS:
- return "Invalid \"configurePresets\" field";
- case ReadFileResult::INVALID_PRESET:
- return "Invalid preset";
- case ReadFileResult::INVALID_VARIABLE:
- return "Invalid CMake variable definition";
- case ReadFileResult::DUPLICATE_PRESETS:
- return "Duplicate presets";
- case ReadFileResult::CYCLIC_PRESET_INHERITANCE:
- return "Cyclic preset inheritance";
- case ReadFileResult::INHERITED_PRESET_UNREACHABLE_FROM_FILE:
- return "Inherited preset is unreachable from preset's file";
- case ReadFileResult::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE:
- return "Configure preset is unreachable from preset's file";
- case ReadFileResult::INVALID_MACRO_EXPANSION:
- return "Invalid macro expansion";
- case ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED:
- return "File version must be 2 or higher for build and test preset "
- "support.";
- case ReadFileResult::PACKAGE_PRESETS_UNSUPPORTED:
- return "File version must be 6 or higher for package preset support";
- case ReadFileResult::WORKFLOW_PRESETS_UNSUPPORTED:
- return "File version must be 6 or higher for workflow preset support";
- case ReadFileResult::INCLUDE_UNSUPPORTED:
- return "File version must be 4 or higher for include support";
- case ReadFileResult::INVALID_INCLUDE:
- return "Invalid \"include\" field";
- case ReadFileResult::INVALID_CONFIGURE_PRESET:
- return "Invalid \"configurePreset\" field";
- case ReadFileResult::INSTALL_PREFIX_UNSUPPORTED:
- return "File version must be 3 or higher for installDir preset "
- "support.";
- case ReadFileResult::INVALID_CONDITION:
- return "Invalid preset condition";
- case ReadFileResult::CONDITION_UNSUPPORTED:
- return "File version must be 3 or higher for condition support";
- case ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED:
- return "File version must be 3 or higher for toolchainFile preset "
- "support.";
- case ReadFileResult::CYCLIC_INCLUDE:
- return "Cyclic include among preset files";
- case ReadFileResult::TEST_OUTPUT_TRUNCATION_UNSUPPORTED:
- return "File version must be 5 or higher for testOutputTruncation "
- "preset support.";
- case ReadFileResult::INVALID_WORKFLOW_STEPS:
- return "Invalid workflow steps";
- case ReadFileResult::WORKFLOW_STEP_UNREACHABLE_FROM_FILE:
- return "Workflow step is unreachable from preset's file";
- case ReadFileResult::CTEST_JUNIT_UNSUPPORTED:
- return "File version must be 6 or higher for CTest JUnit output support";
- }
-
- return "Unknown error";
+ return true;
}
void cmCMakePresetsGraph::ClearPresets()
diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h
index 17c902ba62..9d7e5fac66 100644
--- a/Source/cmCMakePresetsGraph.h
+++ b/Source/cmCMakePresetsGraph.h
@@ -14,6 +14,8 @@
#include <cm/optional>
+#include "cmJSONState.h"
+
#include "CTest/cmCTestTypes.h"
enum class PackageResolveMode;
@@ -21,43 +23,9 @@ enum class PackageResolveMode;
class cmCMakePresetsGraph
{
public:
- enum class ReadFileResult
- {
- READ_OK,
- FILE_NOT_FOUND,
- JSON_PARSE_ERROR,
- INVALID_ROOT,
- NO_VERSION,
- INVALID_VERSION,
- UNRECOGNIZED_VERSION,
- INVALID_CMAKE_VERSION,
- UNRECOGNIZED_CMAKE_VERSION,
- INVALID_PRESETS,
- INVALID_PRESET,
- INVALID_VARIABLE,
- DUPLICATE_PRESETS,
- CYCLIC_PRESET_INHERITANCE,
- INHERITED_PRESET_UNREACHABLE_FROM_FILE,
- CONFIGURE_PRESET_UNREACHABLE_FROM_FILE,
- INVALID_MACRO_EXPANSION,
- BUILD_TEST_PRESETS_UNSUPPORTED,
- PACKAGE_PRESETS_UNSUPPORTED,
- WORKFLOW_PRESETS_UNSUPPORTED,
- INCLUDE_UNSUPPORTED,
- INVALID_INCLUDE,
- INVALID_CONFIGURE_PRESET,
- INSTALL_PREFIX_UNSUPPORTED,
- INVALID_CONDITION,
- CONDITION_UNSUPPORTED,
- TOOLCHAIN_FILE_UNSUPPORTED,
- CYCLIC_INCLUDE,
- TEST_OUTPUT_TRUNCATION_UNSUPPORTED,
- INVALID_WORKFLOW_STEPS,
- WORKFLOW_STEP_UNREACHABLE_FROM_FILE,
- CTEST_JUNIT_UNSUPPORTED,
- };
-
std::string errors;
+ cmJSONState parseState;
+
enum class ArchToolsetStrategy
{
Set,
@@ -111,15 +79,13 @@ public:
std::map<std::string, cm::optional<std::string>> Environment;
- virtual ReadFileResult VisitPresetInherit(const Preset& parent) = 0;
- virtual ReadFileResult VisitPresetBeforeInherit()
- {
- return ReadFileResult::READ_OK;
- }
+ virtual bool VisitPresetInherit(const Preset& parent) = 0;
+ virtual bool VisitPresetBeforeInherit() { return true; }
- virtual ReadFileResult VisitPresetAfterInherit(int /* version */)
+ virtual bool VisitPresetAfterInherit(int /* version */,
+ cmJSONState* /*state*/)
{
- return ReadFileResult::READ_OK;
+ return true;
}
};
@@ -163,9 +129,9 @@ public:
cm::optional<bool> DebugTryCompile;
cm::optional<bool> DebugFind;
- ReadFileResult VisitPresetInherit(const Preset& parent) override;
- ReadFileResult VisitPresetBeforeInherit() override;
- ReadFileResult VisitPresetAfterInherit(int version) override;
+ bool VisitPresetInherit(const Preset& parent) override;
+ bool VisitPresetBeforeInherit() override;
+ bool VisitPresetAfterInherit(int version, cmJSONState* state) override;
};
class BuildPreset : public Preset
@@ -195,8 +161,9 @@ public:
std::vector<std::string> NativeToolOptions;
cm::optional<PackageResolveMode> ResolvePackageReferences;
- ReadFileResult VisitPresetInherit(const Preset& parent) override;
- ReadFileResult VisitPresetAfterInherit(int /* version */) override;
+ bool VisitPresetInherit(const Preset& parent) override;
+ bool VisitPresetAfterInherit(int /* version */,
+ cmJSONState* /*state*/) override;
};
class TestPreset : public Preset
@@ -328,8 +295,9 @@ public:
cm::optional<FilterOptions> Filter;
cm::optional<ExecutionOptions> Execution;
- ReadFileResult VisitPresetInherit(const Preset& parent) override;
- ReadFileResult VisitPresetAfterInherit(int /* version */) override;
+ bool VisitPresetInherit(const Preset& parent) override;
+ bool VisitPresetAfterInherit(int /* version */,
+ cmJSONState* /*state*/) override;
};
class PackagePreset : public Preset
@@ -364,8 +332,9 @@ public:
std::string PackageDirectory;
std::string VendorName;
- ReadFileResult VisitPresetInherit(const Preset& parent) override;
- ReadFileResult VisitPresetAfterInherit(int /* version */) override;
+ bool VisitPresetInherit(const Preset& parent) override;
+ bool VisitPresetAfterInherit(int /* version */,
+ cmJSONState* /*state*/) override;
};
class WorkflowPreset : public Preset
@@ -401,8 +370,9 @@ public:
std::vector<WorkflowStep> Steps;
- ReadFileResult VisitPresetInherit(const Preset& parent) override;
- ReadFileResult VisitPresetAfterInherit(int /* version */) override;
+ bool VisitPresetInherit(const Preset& parent) override;
+ bool VisitPresetAfterInherit(int /* version */,
+ cmJSONState* /* state */) override;
};
template <class T>
@@ -435,9 +405,8 @@ public:
static std::string GetFilename(const std::string& sourceDir);
static std::string GetUserFilename(const std::string& sourceDir);
- ReadFileResult ReadProjectPresets(const std::string& sourceDir,
- bool allowNoFiles = false);
- static const char* ResultToString(ReadFileResult result);
+ bool ReadProjectPresets(const std::string& sourceDir,
+ bool allowNoFiles = false);
std::string GetGeneratorForPreset(const std::string& presetName) const
{
@@ -502,10 +471,9 @@ private:
Included,
};
- ReadFileResult ReadProjectPresetsInternal(bool allowNoFiles);
- ReadFileResult ReadJSONFile(const std::string& filename, RootType rootType,
- ReadReason readReason,
- std::vector<File*>& inProgressFiles, File*& file,
- std::string& errMsg);
+ bool ReadProjectPresetsInternal(bool allowNoFiles);
+ bool ReadJSONFile(const std::string& filename, RootType rootType,
+ ReadReason readReason, std::vector<File*>& inProgressFiles,
+ File*& file, std::string& errMsg);
void ClearPresets();
};
diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h
index 2726e92212..db784c341a 100644
--- a/Source/cmCMakePresetsGraphInternal.h
+++ b/Source/cmCMakePresetsGraphInternal.h
@@ -14,7 +14,7 @@
#define CHECK_OK(expr) \
do { \
auto _result = expr; \
- if (_result != ReadFileResult::READ_OK) \
+ if (_result != true) \
return _result; \
} while (false)
@@ -117,57 +117,56 @@ public:
std::unique_ptr<Condition> SubCondition;
};
-cmCMakePresetsGraph::ReadFileResult PresetStringHelper(
- std::string& out, const Json::Value* value);
+bool PresetStringHelper(std::string& out, const Json::Value* value,
+ cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper(
- std::vector<std::string>& out, const Json::Value* value);
+bool PresetNameHelper(std::string& out, const Json::Value* value,
+ cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out,
- const Json::Value* value);
+bool PresetVectorStringHelper(std::vector<std::string>& out,
+ const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper(
- cm::optional<bool>& out, const Json::Value* value);
+bool PresetBoolHelper(bool& out, const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out,
- const Json::Value* value);
+bool PresetOptionalBoolHelper(cm::optional<bool>& out,
+ const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper(
- cm::optional<int>& out, const Json::Value* value);
+bool PresetIntHelper(int& out, const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper(
- std::vector<int>& out, const Json::Value* value);
+bool PresetOptionalIntHelper(cm::optional<int>& out, const Json::Value* value,
+ cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult ConfigurePresetsHelper(
+bool PresetVectorIntHelper(std::vector<int>& out, const Json::Value* value,
+ cmJSONState* state);
+
+bool ConfigurePresetsHelper(
std::vector<cmCMakePresetsGraph::ConfigurePreset>& out,
- const Json::Value* value);
+ const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult BuildPresetsHelper(
- std::vector<cmCMakePresetsGraph::BuildPreset>& out,
- const Json::Value* value);
+bool BuildPresetsHelper(std::vector<cmCMakePresetsGraph::BuildPreset>& out,
+ const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult TestPresetsHelper(
- std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value);
+bool TestPresetsHelper(std::vector<cmCMakePresetsGraph::TestPreset>& out,
+ const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PackagePresetsHelper(
- std::vector<cmCMakePresetsGraph::PackagePreset>& out,
- const Json::Value* value);
+bool PackagePresetsHelper(std::vector<cmCMakePresetsGraph::PackagePreset>& out,
+ const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult WorkflowPresetsHelper(
+bool WorkflowPresetsHelper(
std::vector<cmCMakePresetsGraph::WorkflowPreset>& out,
- const Json::Value* value);
+ const Json::Value* value, cmJSONState* state);
-cmJSONHelper<std::nullptr_t, cmCMakePresetsGraph::ReadFileResult> VendorHelper(
- cmCMakePresetsGraph::ReadFileResult error);
+cmJSONHelper<std::nullptr_t> VendorHelper(const ErrorGenerator& error);
-cmCMakePresetsGraph::ReadFileResult PresetConditionHelper(
+bool PresetConditionHelper(
std::shared_ptr<cmCMakePresetsGraph::Condition>& out,
- const Json::Value* value);
+ const Json::Value* value, cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult PresetVectorOneOrMoreStringHelper(
- std::vector<std::string>& out, const Json::Value* value);
+bool PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out,
+ const Json::Value* value,
+ cmJSONState* state);
-cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper(
+bool EnvironmentMapHelper(
std::map<std::string, cm::optional<std::string>>& out,
- const Json::Value* value);
+ const Json::Value* value, cmJSONState* state);
}
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index a96ab584de..93c5f7d994 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -1,6 +1,7 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include <algorithm>
+#include <fstream>
#include <functional>
#include <map>
#include <string>
@@ -12,20 +13,18 @@
#include <cm/optional>
#include <cmext/string_view>
-#include <cm3p/json/reader.h>
#include <cm3p/json/value.h>
-#include "cmsys/FStream.hxx"
-
+#include "cmCMakePresetErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
+#include "cmJSONState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
namespace {
-using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using CacheVariable = cmCMakePresetsGraph::CacheVariable;
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
@@ -33,7 +32,7 @@ using TestPreset = cmCMakePresetsGraph::TestPreset;
using PackagePreset = cmCMakePresetsGraph::PackagePreset;
using WorkflowPreset = cmCMakePresetsGraph::WorkflowPreset;
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
-using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
+using JSONHelperBuilder = cmJSONHelperBuilder;
constexpr int MIN_VERSION = 1;
constexpr int MAX_VERSION = 6;
@@ -64,26 +63,23 @@ std::unique_ptr<cmCMakePresetsGraphInternal::NotCondition> InvertCondition(
return retval;
}
-auto const ConditionStringHelper = JSONHelperBuilder::String(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
+auto const ConditionStringHelper = JSONHelperBuilder::String();
-auto const ConditionBoolHelper = JSONHelperBuilder::Bool(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
+auto const ConditionBoolHelper = JSONHelperBuilder::Bool();
auto const ConditionStringListHelper = JSONHelperBuilder::Vector<std::string>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
- ConditionStringHelper);
+ cmCMakePresetErrors::INVALID_CONDITION, ConditionStringHelper);
auto const ConstConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::ConstCondition>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
+ cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value,
ConditionBoolHelper, true);
auto const EqualsConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::EqualsCondition>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
+ cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs,
ConditionStringHelper, true)
@@ -92,7 +88,7 @@ auto const EqualsConditionHelper =
auto const InListConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::InListCondition>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
+ cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String,
ConditionStringHelper, true)
@@ -101,24 +97,22 @@ auto const InListConditionHelper =
auto const MatchesConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::MatchesCondition>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
+ cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String,
ConditionStringHelper, true)
.Bind("regex"_s, &cmCMakePresetsGraphInternal::MatchesCondition::Regex,
ConditionStringHelper, true);
-ReadFileResult SubConditionHelper(
- std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
- const Json::Value* value);
+bool SubConditionHelper(std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
+ const Json::Value* value, cmJSONState* state);
auto const ListConditionVectorHelper =
JSONHelperBuilder::Vector<std::unique_ptr<cmCMakePresetsGraph::Condition>>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
- SubConditionHelper);
+ cmCMakePresetErrors::INVALID_CONDITION, SubConditionHelper);
auto const AnyAllOfConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::AnyAllOfCondition>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
+ cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("conditions"_s,
&cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions,
@@ -126,158 +120,160 @@ auto const AnyAllOfConditionHelper =
auto const NotConditionHelper =
JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::NotCondition>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
+ cmCMakePresetErrors::INVALID_CONDITION_OBJECT, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("condition"_s,
&cmCMakePresetsGraphInternal::NotCondition::SubCondition,
SubConditionHelper);
-ReadFileResult ConditionHelper(
- std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
- const Json::Value* value)
+bool ConditionHelper(std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
+ const Json::Value* value, cmJSONState* state)
{
if (!value) {
out.reset();
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isBool()) {
auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>();
c->Value = value->asBool();
out = std::move(c);
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isNull()) {
out = cm::make_unique<cmCMakePresetsGraphInternal::NullCondition>();
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isObject()) {
if (!value->isMember("type")) {
- return ReadFileResult::INVALID_CONDITION;
+ cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ return false;
}
if (!(*value)["type"].isString()) {
- return ReadFileResult::INVALID_CONDITION;
+ cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ return false;
}
auto type = (*value)["type"].asString();
if (type == "const") {
auto c = cm::make_unique<cmCMakePresetsGraphInternal::ConstCondition>();
- CHECK_OK(ConstConditionHelper(*c, value));
+ CHECK_OK(ConstConditionHelper(*c, value, state));
out = std::move(c);
- return ReadFileResult::READ_OK;
+ return true;
}
if (type == "equals" || type == "notEquals") {
auto c = cm::make_unique<cmCMakePresetsGraphInternal::EqualsCondition>();
- CHECK_OK(EqualsConditionHelper(*c, value));
+ CHECK_OK(EqualsConditionHelper(*c, value, state));
out = std::move(c);
if (type == "notEquals") {
out = InvertCondition(std::move(out));
}
- return ReadFileResult::READ_OK;
+ return true;
}
if (type == "inList" || type == "notInList") {
auto c = cm::make_unique<cmCMakePresetsGraphInternal::InListCondition>();
- CHECK_OK(InListConditionHelper(*c, value));
+ CHECK_OK(InListConditionHelper(*c, value, state));
out = std::move(c);
if (type == "notInList") {
out = InvertCondition(std::move(out));
}
- return ReadFileResult::READ_OK;
+ return true;
}
if (type == "matches" || type == "notMatches") {
auto c =
cm::make_unique<cmCMakePresetsGraphInternal::MatchesCondition>();
- CHECK_OK(MatchesConditionHelper(*c, value));
+ CHECK_OK(MatchesConditionHelper(*c, value, state));
out = std::move(c);
if (type == "notMatches") {
out = InvertCondition(std::move(out));
}
- return ReadFileResult::READ_OK;
+ return true;
}
if (type == "anyOf" || type == "allOf") {
auto c =
cm::make_unique<cmCMakePresetsGraphInternal::AnyAllOfCondition>();
c->StopValue = (type == "anyOf");
- CHECK_OK(AnyAllOfConditionHelper(*c, value));
+ CHECK_OK(AnyAllOfConditionHelper(*c, value, state));
out = std::move(c);
- return ReadFileResult::READ_OK;
+ return true;
}
if (type == "not") {
auto c = cm::make_unique<cmCMakePresetsGraphInternal::NotCondition>();
- CHECK_OK(NotConditionHelper(*c, value));
+ CHECK_OK(NotConditionHelper(*c, value, state));
out = std::move(c);
- return ReadFileResult::READ_OK;
+ return true;
}
}
- return ReadFileResult::INVALID_CONDITION;
+ cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ return false;
}
-ReadFileResult SubConditionHelper(
- std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
- const Json::Value* value)
+bool SubConditionHelper(std::unique_ptr<cmCMakePresetsGraph::Condition>& out,
+ const Json::Value* value, cmJSONState* state)
{
std::unique_ptr<cmCMakePresetsGraph::Condition> ptr;
- auto result = ConditionHelper(ptr, value);
+ auto result = ConditionHelper(ptr, value, state);
if (ptr && ptr->IsNull()) {
- return ReadFileResult::INVALID_CONDITION;
+ cmCMakePresetErrors::INVALID_CONDITION(value, state);
+ return false;
}
out = std::move(ptr);
return result;
}
-ReadFileResult EnvironmentHelper(cm::optional<std::string>& out,
- const Json::Value* value)
+bool EnvironmentHelper(cm::optional<std::string>& out,
+ const Json::Value* value, cmJSONState* state)
{
if (!value || value->isNull()) {
out = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isString()) {
out = value->asString();
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
-auto const VersionIntHelper = JSONHelperBuilder::Int(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
+auto const VersionIntHelper =
+ JSONHelperBuilder::Int(cmCMakePresetErrors::INVALID_VERSION);
auto const VersionHelper = JSONHelperBuilder::Required<int>(
- ReadFileResult::NO_VERSION, VersionIntHelper);
+ cmCMakePresetErrors::NO_VERSION, VersionIntHelper);
auto const RootVersionHelper =
- JSONHelperBuilder::Object<int>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_ROOT)
+ JSONHelperBuilder::Object<int>(cmCMakePresetErrors::INVALID_ROOT_OBJECT)
.Bind("version"_s, VersionHelper, false);
-auto const CMakeVersionUIntHelper = JSONHelperBuilder::UInt(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
+auto const CMakeVersionUIntHelper =
+ JSONHelperBuilder::UInt(cmCMakePresetErrors::INVALID_VERSION);
auto const CMakeVersionHelper =
- JSONHelperBuilder::Object<CMakeVersion>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false)
+ JSONHelperBuilder::Object<CMakeVersion>(JsonErrors::INVALID_NAMED_OBJECT_KEY,
+ false)
.Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false)
.Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false)
.Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false);
-auto const IncludeHelper = JSONHelperBuilder::String(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE);
+auto const IncludeHelper =
+ JSONHelperBuilder::String(cmCMakePresetErrors::INVALID_INCLUDE);
auto const IncludeVectorHelper = JSONHelperBuilder::Vector<std::string>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper);
+ cmCMakePresetErrors::INVALID_INCLUDE, IncludeHelper);
auto const RootPresetsHelper =
- JSONHelperBuilder::Object<RootPresets>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_ROOT, false)
+ JSONHelperBuilder::Object<RootPresets>(
+ cmCMakePresetErrors::INVALID_ROOT_OBJECT, false)
.Bind<int>("version"_s, nullptr, VersionHelper)
.Bind("configurePresets"_s, &RootPresets::ConfigurePresets,
cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false)
@@ -292,136 +288,137 @@ auto const RootPresetsHelper =
.Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired,
CMakeVersionHelper, false)
.Bind("include"_s, &RootPresets::Include, IncludeVectorHelper, false)
- .Bind<std::nullptr_t>(
- "vendor"_s, nullptr,
- cmCMakePresetsGraphInternal::VendorHelper(ReadFileResult::INVALID_ROOT),
- false);
+ .Bind<std::nullptr_t>("vendor"_s, nullptr,
+ cmCMakePresetsGraphInternal::VendorHelper(
+ cmCMakePresetErrors::INVALID_ROOT),
+ false);
}
namespace cmCMakePresetsGraphInternal {
-cmCMakePresetsGraph::ReadFileResult PresetStringHelper(
- std::string& out, const Json::Value* value)
+bool PresetStringHelper(std::string& out, const Json::Value* value,
+ cmJSONState* state)
{
- static auto const helper = JSONHelperBuilder::String(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
+ static auto const helper = JSONHelperBuilder::String();
+ return helper(out, value, state);
+}
- return helper(out, value);
+bool PresetNameHelper(std::string& out, const Json::Value* value,
+ cmJSONState* state)
+{
+ if (!value || !value->isString() || value->asString().empty()) {
+ cmCMakePresetErrors::INVALID_PRESET_NAME(value, state);
+ return false;
+ }
+ out = value->asString();
+ return true;
}
-cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper(
- std::vector<std::string>& out, const Json::Value* value)
+bool PresetVectorStringHelper(std::vector<std::string>& out,
+ const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<std::string>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
+ cmCMakePresetErrors::INVALID_PRESET,
cmCMakePresetsGraphInternal::PresetStringHelper);
-
- return helper(out, value);
+ return helper(out, value, state);
}
-cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out,
- const Json::Value* value)
+bool PresetBoolHelper(bool& out, const Json::Value* value, cmJSONState* state)
{
- static auto const helper = JSONHelperBuilder::Bool(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
-
- return helper(out, value);
+ static auto const helper = JSONHelperBuilder::Bool();
+ return helper(out, value, state);
}
-cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper(
- cm::optional<bool>& out, const Json::Value* value)
+bool PresetOptionalBoolHelper(cm::optional<bool>& out,
+ const Json::Value* value, cmJSONState* state)
{
- static auto const helper = JSONHelperBuilder::Optional<bool>(
- ReadFileResult::READ_OK, PresetBoolHelper);
-
- return helper(out, value);
+ static auto const helper =
+ JSONHelperBuilder::Optional<bool>(PresetBoolHelper);
+ return helper(out, value, state);
}
-cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out,
- const Json::Value* value)
+bool PresetIntHelper(int& out, const Json::Value* value, cmJSONState* state)
{
- static auto const helper = JSONHelperBuilder::Int(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
-
- return helper(out, value);
+ static auto const helper = JSONHelperBuilder::Int();
+ return helper(out, value, state);
}
-cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper(
- cm::optional<int>& out, const Json::Value* value)
+bool PresetOptionalIntHelper(cm::optional<int>& out, const Json::Value* value,
+ cmJSONState* state)
{
- static auto const helper =
- JSONHelperBuilder::Optional<int>(ReadFileResult::READ_OK, PresetIntHelper);
-
- return helper(out, value);
+ static auto const helper = JSONHelperBuilder::Optional<int>(PresetIntHelper);
+ return helper(out, value, state);
}
-cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper(
- std::vector<int>& out, const Json::Value* value)
+bool PresetVectorIntHelper(std::vector<int>& out, const Json::Value* value,
+ cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<int>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper);
-
- return helper(out, value);
+ cmCMakePresetErrors::INVALID_PRESET, PresetIntHelper);
+ return helper(out, value, state);
}
-cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error)
+cmJSONHelper<std::nullptr_t> VendorHelper(const ErrorGenerator& error)
{
- return [error](std::nullptr_t& /*out*/,
- const Json::Value* value) -> ReadFileResult {
+ return [error](std::nullptr_t& /*out*/, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
- return ReadFileResult::READ_OK;
+ return true;
}
if (!value->isObject()) {
- return error;
+ error(value, state);
+ return false;
}
- return ReadFileResult::READ_OK;
+ return true;
};
}
-ReadFileResult PresetConditionHelper(
+bool PresetConditionHelper(
std::shared_ptr<cmCMakePresetsGraph::Condition>& out,
- const Json::Value* value)
+ const Json::Value* value, cmJSONState* state)
{
std::unique_ptr<cmCMakePresetsGraph::Condition> ptr;
- auto result = ConditionHelper(ptr, value);
+ auto result = ConditionHelper(ptr, value, state);
out = std::move(ptr);
return result;
}
-ReadFileResult PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out,
- const Json::Value* value)
+bool PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out,
+ const Json::Value* value,
+ cmJSONState* state)
{
out.clear();
if (!value) {
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isString()) {
out.push_back(value->asString());
- return ReadFileResult::READ_OK;
+ return true;
}
- return PresetVectorStringHelper(out, value);
+ return PresetVectorStringHelper(out, value, state);
}
-cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper(
+bool EnvironmentMapHelper(
std::map<std::string, cm::optional<std::string>>& out,
- const Json::Value* value)
+ const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Map<cm::optional<std::string>>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
- EnvironmentHelper);
+ cmCMakePresetErrors::INVALID_PRESET, EnvironmentHelper);
- return helper(out, value);
+ return helper(out, value, state);
}
}
-cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
- const std::string& filename, RootType rootType, ReadReason readReason,
- std::vector<File*>& inProgressFiles, File*& file, std::string& errMsg)
+bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
+ RootType rootType,
+ ReadReason readReason,
+ std::vector<File*>& inProgressFiles,
+ File*& file, std::string& errMsg)
{
- ReadFileResult result;
+ bool result;
for (auto const& f : this->Files) {
if (cmSystemTools::SameFile(filename, f->Filename)) {
@@ -429,61 +426,67 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
auto fileIt =
std::find(inProgressFiles.begin(), inProgressFiles.end(), file);
if (fileIt != inProgressFiles.end()) {
- return cmCMakePresetsGraph::ReadFileResult::CYCLIC_INCLUDE;
+ cmCMakePresetErrors::CYCLIC_INCLUDE(filename, &this->parseState);
+ return false;
}
- return cmCMakePresetsGraph::ReadFileResult::READ_OK;
+ return true;
}
}
- cmsys::ifstream fin(filename.c_str());
- if (!fin) {
- errMsg = cmStrCat(filename, ": Failed to read file\n", errMsg);
- return ReadFileResult::FILE_NOT_FOUND;
- }
- // If there's a BOM, toss it.
- cmsys::FStream::ReadBOM(fin);
-
Json::Value root;
- Json::CharReaderBuilder builder;
- Json::CharReaderBuilder::strictMode(&builder.settings_);
- if (!Json::parseFromStream(builder, fin, &root, &errMsg)) {
- errMsg = cmStrCat(filename, ":\n", errMsg);
- return ReadFileResult::JSON_PARSE_ERROR;
+ this->parseState = cmJSONState(filename, &root);
+ if (!this->parseState.errors.empty()) {
+ return false;
}
int v = 0;
- if ((result = RootVersionHelper(v, &root)) != ReadFileResult::READ_OK) {
+ if ((result = RootVersionHelper(v, &root, &parseState)) != true) {
return result;
}
if (v < MIN_VERSION || v > MAX_VERSION) {
- return ReadFileResult::UNRECOGNIZED_VERSION;
+ cmCMakePresetErrors::UNRECOGNIZED_VERSION(&root["version"],
+ &this->parseState);
+ return false;
}
// Support for build and test presets added in version 2.
- if (v < 2 &&
- (root.isMember("buildPresets") || root.isMember("testPresets"))) {
- return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED;
+ if (v < 2) {
+ if (root.isMember("buildPresets")) {
+ cmCMakePresetErrors::BUILD_TEST_PRESETS_UNSUPPORTED(
+ &root["buildPresets"], &this->parseState);
+ return false;
+ }
+ if (root.isMember("testPresets")) {
+ cmCMakePresetErrors::BUILD_TEST_PRESETS_UNSUPPORTED(&root["testPresets"],
+ &this->parseState);
+ return false;
+ }
}
// Support for package presets added in version 6.
if (v < 6 && root.isMember("packagePresets")) {
- return ReadFileResult::PACKAGE_PRESETS_UNSUPPORTED;
+ cmCMakePresetErrors::PACKAGE_PRESETS_UNSUPPORTED(&root["packagePresets"],
+ &this->parseState);
+ return false;
}
// Support for workflow presets added in version 6.
if (v < 6 && root.isMember("workflowPresets")) {
- return ReadFileResult::WORKFLOW_PRESETS_UNSUPPORTED;
+ cmCMakePresetErrors::WORKFLOW_PRESETS_UNSUPPORTED(&root["workflowPresets"],
+ &this->parseState);
+ return false;
}
// Support for include added in version 4.
if (v < 4 && root.isMember("include")) {
- return ReadFileResult::INCLUDE_UNSUPPORTED;
+ cmCMakePresetErrors::INCLUDE_UNSUPPORTED(&root["include"],
+ &this->parseState);
+ return false;
}
RootPresets presets;
- if ((result = RootPresetsHelper(presets, &root)) !=
- ReadFileResult::READ_OK) {
+ if ((result = RootPresetsHelper(presets, &root, &parseState)) != true) {
return result;
}
@@ -491,12 +494,25 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
unsigned int currentMinor = cmVersion::GetMinorVersion();
unsigned int currentPatch = cmVersion::GetPatchVersion();
auto const& required = presets.CMakeMinimumRequired;
- if (required.Major > currentMajor ||
- (required.Major == currentMajor &&
- (required.Minor > currentMinor ||
- (required.Minor == currentMinor &&
- (required.Patch > currentPatch))))) {
- return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION;
+ if (required.Major > currentMajor) {
+ ErrorGenerator error = cmCMakePresetErrors::UNRECOGNIZED_CMAKE_VERSION(
+ "major", currentMajor, required.Major);
+ error(&root["cmakeMinimumRequired"]["major"], &this->parseState);
+ return false;
+ }
+ if (required.Major == currentMajor) {
+ if (required.Minor > currentMinor) {
+ ErrorGenerator error = cmCMakePresetErrors::UNRECOGNIZED_CMAKE_VERSION(
+ "minor", currentMinor, required.Minor);
+ error(&root["cmakeMinimumRequired"]["minor"], &this->parseState);
+ return false;
+ }
+ if (required.Minor == currentMinor && required.Patch > currentPatch) {
+ ErrorGenerator error = cmCMakePresetErrors::UNRECOGNIZED_CMAKE_VERSION(
+ "patch", currentPatch, required.Patch);
+ error(&root["cmakeMinimumRequired"]["patch"], &this->parseState);
+ return false;
+ }
}
auto filePtr = cm::make_unique<File>();
@@ -510,31 +526,35 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
for (auto& preset : presets.ConfigurePresets) {
preset.OriginFile = file;
if (preset.Name.empty()) {
- errMsg += R"(\n\t)";
- errMsg += filename;
- return ReadFileResult::INVALID_PRESET;
+ // No error, already handled by PresetNameHelper
+ return false;
}
PresetPair<ConfigurePreset> presetPair;
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->ConfigurePresets.emplace(preset.Name, presetPair).second) {
- return ReadFileResult::DUPLICATE_PRESETS;
+ cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ return false;
}
// Support for installDir presets added in version 3.
if (v < 3 && !preset.InstallDir.empty()) {
- return ReadFileResult::INSTALL_PREFIX_UNSUPPORTED;
+ cmCMakePresetErrors::INSTALL_PREFIX_UNSUPPORTED(&root["installDir"],
+ &this->parseState);
+ return false;
}
// Support for conditions added in version 3.
if (v < 3 && preset.ConditionEvaluator) {
- return ReadFileResult::CONDITION_UNSUPPORTED;
+ cmCMakePresetErrors::CONDITION_UNSUPPORTED(&this->parseState);
+ return false;
}
// Support for toolchainFile presets added in version 3.
if (v < 3 && !preset.ToolchainFile.empty()) {
- return ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED;
+ cmCMakePresetErrors::TOOLCHAIN_FILE_UNSUPPORTED(&this->parseState);
+ return false;
}
this->ConfigurePresetOrder.push_back(preset.Name);
@@ -543,21 +563,22 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
for (auto& preset : presets.BuildPresets) {
preset.OriginFile = file;
if (preset.Name.empty()) {
- errMsg += R"(\n\t)";
- errMsg += filename;
- return ReadFileResult::INVALID_PRESET;
+ // No error, already handled by PresetNameHelper
+ return false;
}
PresetPair<BuildPreset> presetPair;
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->BuildPresets.emplace(preset.Name, presetPair).second) {
- return ReadFileResult::DUPLICATE_PRESETS;
+ cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ return false;
}
// Support for conditions added in version 3.
if (v < 3 && preset.ConditionEvaluator) {
- return ReadFileResult::CONDITION_UNSUPPORTED;
+ cmCMakePresetErrors::CONDITION_UNSUPPORTED(&this->parseState);
+ return false;
}
this->BuildPresetOrder.push_back(preset.Name);
@@ -566,29 +587,35 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
for (auto& preset : presets.TestPresets) {
preset.OriginFile = file;
if (preset.Name.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ // No error, already handled by PresetNameHelper
+ return false;
}
PresetPair<TestPreset> presetPair;
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->TestPresets.emplace(preset.Name, presetPair).second) {
- return ReadFileResult::DUPLICATE_PRESETS;
+ cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ return false;
}
// Support for conditions added in version 3.
if (v < 3 && preset.ConditionEvaluator) {
- return ReadFileResult::CONDITION_UNSUPPORTED;
+ cmCMakePresetErrors::CONDITION_UNSUPPORTED(&this->parseState);
+ return false;
}
// Support for TestOutputTruncation added in version 5.
if (v < 5 && preset.Output && preset.Output->TestOutputTruncation) {
- return ReadFileResult::TEST_OUTPUT_TRUNCATION_UNSUPPORTED;
+ cmCMakePresetErrors::TEST_OUTPUT_TRUNCATION_UNSUPPORTED(
+ &this->parseState);
+ return false;
}
// Support for outputJUnitFile added in version 6.
if (v < 6 && preset.Output && !preset.Output->OutputJUnitFile.empty()) {
- return ReadFileResult::CTEST_JUNIT_UNSUPPORTED;
+ cmCMakePresetErrors::CTEST_JUNIT_UNSUPPORTED(&this->parseState);
+ return false;
}
this->TestPresetOrder.push_back(preset.Name);
@@ -597,14 +624,16 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
for (auto& preset : presets.PackagePresets) {
preset.OriginFile = file;
if (preset.Name.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ // No error, already handled by PresetNameHelper
+ return false;
}
PresetPair<PackagePreset> presetPair;
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->PackagePresets.emplace(preset.Name, presetPair).second) {
- return ReadFileResult::DUPLICATE_PRESETS;
+ cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ return false;
}
// Support for conditions added in version 3, but this requires version 5
@@ -616,14 +645,16 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
for (auto& preset : presets.WorkflowPresets) {
preset.OriginFile = file;
if (preset.Name.empty()) {
- return ReadFileResult::INVALID_PRESET;
+ // No error, already handled by PresetNameHelper
+ return false;
}
PresetPair<WorkflowPreset> presetPair;
presetPair.Unexpanded = preset;
presetPair.Expanded = cm::nullopt;
if (!this->WorkflowPresets.emplace(preset.Name, presetPair).second) {
- return ReadFileResult::DUPLICATE_PRESETS;
+ cmCMakePresetErrors::DUPLICATE_PRESETS(preset.Name, &this->parseState);
+ return false;
}
// Support for conditions added in version 3, but this requires version 6
@@ -632,21 +663,21 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
this->WorkflowPresetOrder.push_back(preset.Name);
}
- auto const includeFile = [this, &inProgressFiles, file](
- const std::string& include, RootType rootType2,
- ReadReason readReason2,
- std::string& FailureMessage) -> ReadFileResult {
- ReadFileResult r;
+ auto const includeFile = [this, &inProgressFiles,
+ file](const std::string& include,
+ RootType rootType2, ReadReason readReason2,
+ std::string& FailureMessage) -> bool {
+ bool r;
File* includedFile;
- if ((r = this->ReadJSONFile(include, rootType2, readReason2,
- inProgressFiles, includedFile,
- FailureMessage)) != ReadFileResult::READ_OK) {
+ if ((r =
+ this->ReadJSONFile(include, rootType2, readReason2, inProgressFiles,
+ includedFile, FailureMessage)) != true) {
return r;
}
file->ReachableFiles.insert(includedFile->ReachableFiles.begin(),
includedFile->ReachableFiles.end());
- return ReadFileResult::READ_OK;
+ return true;
};
for (auto include : presets.Include) {
@@ -656,7 +687,7 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
}
if ((result = includeFile(include, rootType, ReadReason::Included,
- errMsg)) != ReadFileResult::READ_OK) {
+ errMsg)) != true) {
return result;
}
}
@@ -665,13 +696,12 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
auto cmakePresetsFilename = GetFilename(this->SourceDir);
if (cmSystemTools::FileExists(cmakePresetsFilename)) {
if ((result = includeFile(cmakePresetsFilename, RootType::Project,
- ReadReason::Root, errMsg)) !=
- ReadFileResult::READ_OK) {
+ ReadReason::Root, errMsg)) != true) {
return result;
}
}
}
inProgressFiles.pop_back();
- return ReadFileResult::READ_OK;
+ return true;
}
diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
index 430d7ee3a2..07f2bc34e0 100644
--- a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
@@ -13,25 +13,27 @@
#include <cm3p/json/value.h>
#include "cmBuildOptions.h"
+#include "cmCMakePresetErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
+class cmJSONState;
namespace {
-using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
-using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
+using JSONHelperBuilder = cmJSONHelperBuilder;
-ReadFileResult PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
- const Json::Value* value)
+bool PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
+ const Json::Value* value, cmJSONState* state)
{
if (!value) {
out = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
if (!value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (value->asString() == "on") {
@@ -41,23 +43,25 @@ ReadFileResult PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
} else if (value->asString() == "only") {
out = PackageResolveMode::OnlyResolve;
} else {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
- return ReadFileResult::READ_OK;
+ return true;
}
-std::function<ReadFileResult(BuildPreset&, const Json::Value*)> const
- ResolvePackageReferencesHelper =
- [](BuildPreset& out, const Json::Value* value) -> ReadFileResult {
- return PackageResolveModeHelper(out.ResolvePackageReferences, value);
+std::function<bool(BuildPreset&, const Json::Value*, cmJSONState*)> const
+ ResolvePackageReferencesHelper = [](BuildPreset& out,
+ const Json::Value* value,
+ cmJSONState* state) -> bool {
+ return PackageResolveModeHelper(out.ResolvePackageReferences, value, state);
};
auto const BuildPresetHelper =
- JSONHelperBuilder::Object<BuildPreset>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_PRESET, false)
+ JSONHelperBuilder::Object<BuildPreset>(
+ cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &BuildPreset::Name,
- cmCMakePresetsGraphInternal::PresetStringHelper)
+ cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &BuildPreset::Inherits,
cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
false)
@@ -65,7 +69,7 @@ auto const BuildPresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- ReadFileResult::INVALID_PRESET),
+ cmCMakePresetErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &BuildPreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -97,13 +101,12 @@ auto const BuildPresetHelper =
}
namespace cmCMakePresetsGraphInternal {
-ReadFileResult BuildPresetsHelper(std::vector<BuildPreset>& out,
- const Json::Value* value)
+bool BuildPresetsHelper(std::vector<BuildPreset>& out,
+ const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<BuildPreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
- BuildPresetHelper);
+ cmCMakePresetErrors::INVALID_PRESETS, BuildPresetHelper);
- return helper(out, value);
+ return helper(out, value, state);
}
}
diff --git a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
index 7cff55a01b..a1774be42f 100644
--- a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
@@ -12,72 +12,77 @@
#include <cm3p/json/value.h>
+#include "cmCMakePresetErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
+#include "cmJSONState.h"
namespace {
-using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using CacheVariable = cmCMakePresetsGraph::CacheVariable;
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
-using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
+using JSONHelperBuilder = cmJSONHelperBuilder;
-ReadFileResult ArchToolsetStrategyHelper(
- cm::optional<ArchToolsetStrategy>& out, const Json::Value* value)
+bool ArchToolsetStrategyHelper(cm::optional<ArchToolsetStrategy>& out,
+ const Json::Value* value, cmJSONState* state)
{
if (!value) {
out = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
if (!value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (value->asString() == "set") {
out = ArchToolsetStrategy::Set;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "external") {
out = ArchToolsetStrategy::External;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
-std::function<ReadFileResult(ConfigurePreset&, const Json::Value*)>
+std::function<bool(ConfigurePreset&, const Json::Value*, cmJSONState*)>
ArchToolsetHelper(
std::string ConfigurePreset::*valueField,
cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField)
{
auto const objectHelper =
- JSONHelperBuilder::Object<ConfigurePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ JSONHelperBuilder::Object<ConfigurePreset>(JsonErrors::INVALID_OBJECT,
+ false)
.Bind("value", valueField,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
.Bind("strategy", strategyField, ArchToolsetStrategyHelper, false);
- return [valueField, strategyField, objectHelper](
- ConfigurePreset& out, const Json::Value* value) -> ReadFileResult {
+ return [valueField, strategyField,
+ objectHelper](ConfigurePreset& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
(out.*valueField).clear();
out.*strategyField = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isString()) {
out.*valueField = value->asString();
out.*strategyField = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isObject()) {
- return objectHelper(out, value);
+ return objectHelper(out, value, state);
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
};
}
@@ -86,65 +91,66 @@ auto const ArchitectureHelper = ArchToolsetHelper(
auto const ToolsetHelper = ArchToolsetHelper(
&ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy);
-auto const VariableStringHelper = JSONHelperBuilder::String(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE);
+auto const VariableStringHelper = JSONHelperBuilder::String();
-ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value)
+bool VariableValueHelper(std::string& out, const Json::Value* value,
+ cmJSONState* state)
{
if (!value) {
out.clear();
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isBool()) {
out = value->asBool() ? "TRUE" : "FALSE";
- return ReadFileResult::READ_OK;
+ return true;
}
- return VariableStringHelper(out, value);
+ return VariableStringHelper(out, value, state);
}
auto const VariableObjectHelper =
JSONHelperBuilder::Object<CacheVariable>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false)
+ cmCMakePresetErrors::INVALID_VARIABLE_OBJECT, false)
.Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
.Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
-ReadFileResult VariableHelper(cm::optional<CacheVariable>& out,
- const Json::Value* value)
+bool VariableHelper(cm::optional<CacheVariable>& out, const Json::Value* value,
+ cmJSONState* state)
{
if (value->isBool()) {
out = CacheVariable{
/*Type=*/"BOOL",
/*Value=*/value->asBool() ? "TRUE" : "FALSE",
};
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isString()) {
out = CacheVariable{
/*Type=*/"",
/*Value=*/value->asString(),
};
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isObject()) {
out.emplace();
- return VariableObjectHelper(*out, value);
+ return VariableObjectHelper(*out, value, state);
}
if (value->isNull()) {
out = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_VARIABLE;
+ cmCMakePresetErrors::INVALID_VARIABLE(value, state);
+ return false;
}
auto const VariablesHelper =
JSONHelperBuilder::Map<cm::optional<CacheVariable>>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper);
+ cmCMakePresetErrors::INVALID_PRESET, VariableHelper);
auto const PresetWarningsHelper =
JSONHelperBuilder::Object<ConfigurePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
.Bind("dev"_s, &ConfigurePreset::WarnDev,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
.Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated,
@@ -158,7 +164,7 @@ auto const PresetWarningsHelper =
auto const PresetErrorsHelper =
JSONHelperBuilder::Object<ConfigurePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
.Bind("dev"_s, &ConfigurePreset::ErrorDev,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
.Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated,
@@ -166,7 +172,7 @@ auto const PresetErrorsHelper =
auto const PresetDebugHelper =
JSONHelperBuilder::Object<ConfigurePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
.Bind("output"_s, &ConfigurePreset::DebugOutput,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
.Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile,
@@ -176,9 +182,9 @@ auto const PresetDebugHelper =
auto const ConfigurePresetHelper =
JSONHelperBuilder::Object<ConfigurePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &ConfigurePreset::Name,
- cmCMakePresetsGraphInternal::PresetStringHelper)
+ cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &ConfigurePreset::Inherits,
cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
false)
@@ -186,7 +192,7 @@ auto const ConfigurePresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- ReadFileResult::INVALID_PRESET),
+ cmCMakePresetErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &ConfigurePreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -216,13 +222,12 @@ auto const ConfigurePresetHelper =
}
namespace cmCMakePresetsGraphInternal {
-ReadFileResult ConfigurePresetsHelper(std::vector<ConfigurePreset>& out,
- const Json::Value* value)
+bool ConfigurePresetsHelper(std::vector<ConfigurePreset>& out,
+ const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
- ConfigurePresetHelper);
+ cmCMakePresetErrors::INVALID_PRESETS, ConfigurePresetHelper);
- return helper(out, value);
+ return helper(out, value, state);
}
}
diff --git a/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
index 4ae51b1fc6..7290d4defa 100644
--- a/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
@@ -12,34 +12,34 @@
#include <cm3p/json/value.h>
+#include "cmCMakePresetErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
+class cmJSONState;
namespace {
-using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using PackagePreset = cmCMakePresetsGraph::PackagePreset;
auto const OutputHelper =
- cmJSONHelperBuilder<ReadFileResult>::Object<PackagePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ cmJSONHelperBuilder::Object<PackagePreset>(
+ JsonErrors::INVALID_NAMED_OBJECT_KEY, false)
.Bind("debug"_s, &PackagePreset::DebugOutput,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
.Bind("verbose"_s, &PackagePreset::VerboseOutput,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
-auto const VariableHelper = cmJSONHelperBuilder<ReadFileResult>::String(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE);
+auto const VariableHelper =
+ cmJSONHelperBuilder::String(cmCMakePresetErrors::INVALID_VARIABLE);
-auto const VariablesHelper =
- cmJSONHelperBuilder<ReadFileResult>::Map<std::string>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper);
+auto const VariablesHelper = cmJSONHelperBuilder::Map<std::string>(
+ cmCMakePresetErrors::INVALID_VARIABLE, VariableHelper);
auto const PackagePresetHelper =
- cmJSONHelperBuilder<ReadFileResult>::Object<PackagePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ cmJSONHelperBuilder::Object<PackagePreset>(
+ cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &PackagePreset::Name,
- cmCMakePresetsGraphInternal::PresetStringHelper)
+ cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &PackagePreset::Inherits,
cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
false)
@@ -47,7 +47,7 @@ auto const PackagePresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- ReadFileResult::INVALID_PRESET),
+ cmCMakePresetErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &PackagePreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -81,15 +81,12 @@ auto const PackagePresetHelper =
}
namespace cmCMakePresetsGraphInternal {
-cmCMakePresetsGraph::ReadFileResult PackagePresetsHelper(
- std::vector<cmCMakePresetsGraph::PackagePreset>& out,
- const Json::Value* value)
+bool PackagePresetsHelper(std::vector<cmCMakePresetsGraph::PackagePreset>& out,
+ const Json::Value* value, cmJSONState* state)
{
- static auto const helper =
- cmJSONHelperBuilder<ReadFileResult>::Vector<PackagePreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
- PackagePresetHelper);
+ static auto const helper = cmJSONHelperBuilder::Vector<PackagePreset>(
+ cmCMakePresetErrors::INVALID_PRESETS, PackagePresetHelper);
- return helper(out, value);
+ return helper(out, value, state);
}
}
diff --git a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
index 3856f630c5..791be04a58 100644
--- a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
@@ -12,86 +12,93 @@
#include <cm3p/json/value.h>
+#include "cmCMakePresetErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
#include "CTest/cmCTestTypes.h"
+class cmJSONState;
+
namespace {
-using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using TestPreset = cmCMakePresetsGraph::TestPreset;
-using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
+using JSONHelperBuilder = cmJSONHelperBuilder;
-ReadFileResult TestPresetOutputVerbosityHelper(
- TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value)
+bool TestPresetOutputVerbosityHelper(
+ TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value,
+ cmJSONState* state)
{
if (!value) {
out = TestPreset::OutputOptions::VerbosityEnum::Default;
- return ReadFileResult::READ_OK;
+ return true;
}
if (!value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (value->asString() == "default") {
out = TestPreset::OutputOptions::VerbosityEnum::Default;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "verbose") {
out = TestPreset::OutputOptions::VerbosityEnum::Verbose;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "extra") {
out = TestPreset::OutputOptions::VerbosityEnum::Extra;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
auto const TestPresetOptionalOutputVerbosityHelper =
JSONHelperBuilder::Optional<TestPreset::OutputOptions::VerbosityEnum>(
- ReadFileResult::READ_OK, TestPresetOutputVerbosityHelper);
+ TestPresetOutputVerbosityHelper);
-ReadFileResult TestPresetOutputTruncationHelper(
- cm::optional<cmCTestTypes::TruncationMode>& out, const Json::Value* value)
+bool TestPresetOutputTruncationHelper(
+ cm::optional<cmCTestTypes::TruncationMode>& out, const Json::Value* value,
+ cmJSONState* state)
{
if (!value) {
out = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
if (!value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (value->asString() == "tail") {
out = cmCTestTypes::TruncationMode::Tail;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "middle") {
out = cmCTestTypes::TruncationMode::Middle;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "head") {
out = cmCTestTypes::TruncationMode::Head;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
auto const TestPresetOptionalOutputHelper =
JSONHelperBuilder::Optional<TestPreset::OutputOptions>(
- ReadFileResult::READ_OK,
JSONHelperBuilder::Object<TestPreset::OutputOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ JsonErrors::INVALID_OBJECT, false)
.Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
.Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity,
@@ -125,9 +132,7 @@ auto const TestPresetOptionalOutputHelper =
auto const TestPresetOptionalFilterIncludeIndexObjectHelper =
JSONHelperBuilder::Optional<TestPreset::IncludeOptions::IndexOptions>(
- ReadFileResult::READ_OK,
- JSONHelperBuilder::Object<TestPreset::IncludeOptions::IndexOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::IncludeOptions::IndexOptions>()
.Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start,
cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false)
.Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End,
@@ -138,33 +143,31 @@ auto const TestPresetOptionalFilterIncludeIndexObjectHelper =
&TestPreset::IncludeOptions::IndexOptions::SpecificTests,
cmCMakePresetsGraphInternal::PresetVectorIntHelper, false));
-ReadFileResult TestPresetOptionalFilterIncludeIndexHelper(
+bool TestPresetOptionalFilterIncludeIndexHelper(
cm::optional<TestPreset::IncludeOptions::IndexOptions>& out,
- const Json::Value* value)
+ const Json::Value* value, cmJSONState* state)
{
if (!value) {
out = cm::nullopt;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isString()) {
out.emplace();
out->IndexFile = value->asString();
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->isObject()) {
- return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value);
+ return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value, state);
}
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
auto const TestPresetOptionalFilterIncludeHelper =
JSONHelperBuilder::Optional<TestPreset::IncludeOptions>(
- ReadFileResult::READ_OK,
- JSONHelperBuilder::Object<TestPreset::IncludeOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::IncludeOptions>()
.Bind("name"_s, &TestPreset::IncludeOptions::Name,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
.Bind("label"_s, &TestPreset::IncludeOptions::Label,
@@ -176,9 +179,7 @@ auto const TestPresetOptionalFilterIncludeHelper =
auto const TestPresetOptionalFilterExcludeFixturesHelper =
JSONHelperBuilder::Optional<TestPreset::ExcludeOptions::FixturesOptions>(
- ReadFileResult::READ_OK,
- JSONHelperBuilder::Object<TestPreset::ExcludeOptions::FixturesOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::ExcludeOptions::FixturesOptions>()
.Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
.Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup,
@@ -188,9 +189,7 @@ auto const TestPresetOptionalFilterExcludeFixturesHelper =
auto const TestPresetOptionalFilterExcludeHelper =
JSONHelperBuilder::Optional<TestPreset::ExcludeOptions>(
- ReadFileResult::READ_OK,
- JSONHelperBuilder::Object<TestPreset::ExcludeOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::ExcludeOptions>()
.Bind("name"_s, &TestPreset::ExcludeOptions::Name,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
.Bind("label"_s, &TestPreset::ExcludeOptions::Label,
@@ -198,110 +197,113 @@ auto const TestPresetOptionalFilterExcludeHelper =
.Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures,
TestPresetOptionalFilterExcludeFixturesHelper, false));
-ReadFileResult TestPresetExecutionShowOnlyHelper(
- TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value)
+bool TestPresetExecutionShowOnlyHelper(
+ TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value,
+ cmJSONState* state)
{
if (!value || !value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (value->asString() == "human") {
out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "json-v1") {
out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
auto const TestPresetOptionalExecutionShowOnlyHelper =
JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::ShowOnlyEnum>(
- ReadFileResult::READ_OK, TestPresetExecutionShowOnlyHelper);
+ TestPresetExecutionShowOnlyHelper);
-ReadFileResult TestPresetExecutionModeHelper(
+bool TestPresetExecutionModeHelper(
TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out,
- const Json::Value* value)
+ const Json::Value* value, cmJSONState* state)
{
if (!value) {
- return ReadFileResult::READ_OK;
+ return true;
}
if (!value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (value->asString() == "until-fail") {
out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "until-pass") {
out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "after-timeout") {
out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
auto const TestPresetOptionalExecutionRepeatHelper =
JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::RepeatOptions>(
- ReadFileResult::READ_OK,
- JSONHelperBuilder::Object<TestPreset::ExecutionOptions::RepeatOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::ExecutionOptions::RepeatOptions>()
.Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode,
TestPresetExecutionModeHelper, true)
.Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count,
cmCMakePresetsGraphInternal::PresetIntHelper, true));
-ReadFileResult TestPresetExecutionNoTestsActionHelper(
+bool TestPresetExecutionNoTestsActionHelper(
TestPreset::ExecutionOptions::NoTestsActionEnum& out,
- const Json::Value* value)
+ const Json::Value* value, cmJSONState* state)
{
if (!value) {
out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default;
- return ReadFileResult::READ_OK;
+ return true;
}
if (!value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (value->asString() == "default") {
out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "error") {
out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "ignore") {
out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
auto const TestPresetOptionalExecutionNoTestsActionHelper =
JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::NoTestsActionEnum>(
- ReadFileResult::READ_OK, TestPresetExecutionNoTestsActionHelper);
+ TestPresetExecutionNoTestsActionHelper);
auto const TestPresetExecutionHelper =
JSONHelperBuilder::Optional<TestPreset::ExecutionOptions>(
- ReadFileResult::READ_OK,
- JSONHelperBuilder::Object<TestPreset::ExecutionOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::ExecutionOptions>()
.Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
.Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover,
@@ -329,19 +331,17 @@ auto const TestPresetExecutionHelper =
auto const TestPresetFilterHelper =
JSONHelperBuilder::Optional<TestPreset::FilterOptions>(
- ReadFileResult::READ_OK,
- JSONHelperBuilder::Object<TestPreset::FilterOptions>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::FilterOptions>()
.Bind("include"_s, &TestPreset::FilterOptions::Include,
TestPresetOptionalFilterIncludeHelper, false)
.Bind("exclude"_s, &TestPreset::FilterOptions::Exclude,
TestPresetOptionalFilterExcludeHelper, false));
auto const TestPresetHelper =
- JSONHelperBuilder::Object<TestPreset>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_PRESET, false)
+ JSONHelperBuilder::Object<TestPreset>(
+ cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &TestPreset::Name,
- cmCMakePresetsGraphInternal::PresetStringHelper)
+ cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind("inherits"_s, &TestPreset::Inherits,
cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
false)
@@ -349,7 +349,7 @@ auto const TestPresetHelper =
cmCMakePresetsGraphInternal::PresetBoolHelper, false)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- ReadFileResult::INVALID_PRESET),
+ cmCMakePresetErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &TestPreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -377,13 +377,12 @@ auto const TestPresetHelper =
}
namespace cmCMakePresetsGraphInternal {
-cmCMakePresetsGraph::ReadFileResult TestPresetsHelper(
- std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value)
+bool TestPresetsHelper(std::vector<cmCMakePresetsGraph::TestPreset>& out,
+ const Json::Value* value, cmJSONState* state)
{
static auto const helper = JSONHelperBuilder::Vector<TestPreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
- TestPresetHelper);
+ cmCMakePresetErrors::INVALID_PRESETS, TestPresetHelper);
- return helper(out, value);
+ return helper(out, value, state);
}
}
diff --git a/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx b/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
index 33680a1829..7224e17d60 100644
--- a/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
@@ -9,69 +9,72 @@
#include <cm3p/json/value.h>
+#include "cmCMakePresetErrors.h"
#include "cmCMakePresetsGraph.h"
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
+class cmJSONState;
+
namespace {
-using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using WorkflowPreset = cmCMakePresetsGraph::WorkflowPreset;
-ReadFileResult WorkflowStepTypeHelper(WorkflowPreset::WorkflowStep::Type& out,
- const Json::Value* value)
+bool WorkflowStepTypeHelper(WorkflowPreset::WorkflowStep::Type& out,
+ const Json::Value* value, cmJSONState* state)
{
if (!value) {
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
if (!value->isString()) {
- return ReadFileResult::INVALID_PRESET;
+ return false;
}
if (value->asString() == "configure") {
out = WorkflowPreset::WorkflowStep::Type::Configure;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "build") {
out = WorkflowPreset::WorkflowStep::Type::Build;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "test") {
out = WorkflowPreset::WorkflowStep::Type::Test;
- return ReadFileResult::READ_OK;
+ return true;
}
if (value->asString() == "package") {
out = WorkflowPreset::WorkflowStep::Type::Package;
- return ReadFileResult::READ_OK;
+ return true;
}
- return ReadFileResult::INVALID_PRESET;
+ cmCMakePresetErrors::INVALID_PRESET(value, state);
+ return false;
}
auto const WorkflowStepHelper =
- cmJSONHelperBuilder<ReadFileResult>::Object<WorkflowPreset::WorkflowStep>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ cmJSONHelperBuilder::Object<WorkflowPreset::WorkflowStep>(
+ JsonErrors::INVALID_OBJECT, false)
.Bind("type"_s, &WorkflowPreset::WorkflowStep::PresetType,
WorkflowStepTypeHelper)
.Bind("name"_s, &WorkflowPreset::WorkflowStep::PresetName,
cmCMakePresetsGraphInternal::PresetStringHelper);
auto const WorkflowStepsHelper =
- cmJSONHelperBuilder<ReadFileResult>::Vector<WorkflowPreset::WorkflowStep>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
- WorkflowStepHelper);
+ cmJSONHelperBuilder::Vector<WorkflowPreset::WorkflowStep>(
+ cmCMakePresetErrors::INVALID_PRESET, WorkflowStepHelper);
auto const WorkflowPresetHelper =
- cmJSONHelperBuilder<ReadFileResult>::Object<WorkflowPreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ cmJSONHelperBuilder::Object<WorkflowPreset>(
+ cmCMakePresetErrors::INVALID_PRESET_OBJECT, false)
.Bind("name"_s, &WorkflowPreset::Name,
- cmCMakePresetsGraphInternal::PresetStringHelper)
+ cmCMakePresetsGraphInternal::PresetNameHelper)
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
- ReadFileResult::INVALID_PRESET),
+ cmCMakePresetErrors::INVALID_PRESET),
false)
.Bind("displayName"_s, &WorkflowPreset::DisplayName,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -81,15 +84,13 @@ auto const WorkflowPresetHelper =
}
namespace cmCMakePresetsGraphInternal {
-cmCMakePresetsGraph::ReadFileResult WorkflowPresetsHelper(
+bool WorkflowPresetsHelper(
std::vector<cmCMakePresetsGraph::WorkflowPreset>& out,
- const Json::Value* value)
+ const Json::Value* value, cmJSONState* state)
{
- static auto const helper =
- cmJSONHelperBuilder<ReadFileResult>::Vector<WorkflowPreset>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
- WorkflowPresetHelper);
+ static auto const helper = cmJSONHelperBuilder::Vector<WorkflowPreset>(
+ cmCMakePresetErrors::INVALID_PRESETS, WorkflowPresetHelper);
- return helper(out, value);
+ return helper(out, value, state);
}
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 5899a61b43..c8eea38b75 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -54,6 +54,7 @@
#include "cmDynamicLoader.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmJSONState.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmState.h"
@@ -2336,10 +2337,10 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName,
cmCMakePresetsGraph settingsFile;
auto result = settingsFile.ReadProjectPresets(workingDirectory);
- if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
- cmSystemTools::Error(
- cmStrCat("Could not read presets from ", workingDirectory, ": ",
- cmCMakePresetsGraph::ResultToString(result)));
+ if (result != true) {
+ cmSystemTools::Error(cmStrCat("Could not read presets from ",
+ workingDirectory, ":",
+ settingsFile.parseState.GetErrorMessage()));
return false;
}
diff --git a/Source/cmJSONHelpers.h b/Source/cmJSONHelpers.h
index f7151b52f8..94641deab0 100644
--- a/Source/cmJSONHelpers.h
+++ b/Source/cmJSONHelpers.h
@@ -2,9 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include "cmConfigure.h" // IWYU pragma: keep
+
#include <algorithm>
#include <cstddef>
#include <functional>
+#include <iostream>
#include <map>
#include <string>
#include <vector>
@@ -14,20 +17,129 @@
#include <cm3p/json/value.h>
-template <typename T, typename E, typename... CallState>
+#include "cmJSONState.h"
+
+template <typename T>
using cmJSONHelper =
- std::function<E(T& out, const Json::Value* value, CallState&&... state)>;
+ std::function<bool(T& out, const Json::Value* value, cmJSONState* state)>;
+
+using ErrorGenerator = std::function<void(const Json::Value*, cmJSONState*)>;
+
+namespace JsonErrors {
+enum ObjectError
+{
+ RequiredMissing,
+ InvalidObject,
+ ExtraField,
+ MissingRequired
+};
+using ErrorGenerator = std::function<void(const Json::Value*, cmJSONState*)>;
+using ObjectErrorGenerator =
+ std::function<ErrorGenerator(ObjectError, const Json::Value::Members&)>;
+const auto EXPECTED_TYPE = [](const std::string& type) {
+ return [type](const Json::Value* value, cmJSONState* state) -> void {
+#if !defined(CMAKE_BOOTSTRAP)
+ if (state->key().empty()) {
+ state->AddErrorAtValue(cmStrCat("Expected ", type), value);
+ return;
+ }
+ std::string errMsg = cmStrCat("\"", state->key(), "\" expected ", type);
+ if (value && value->isConvertibleTo(Json::ValueType::stringValue)) {
+ errMsg = cmStrCat(errMsg, ", got: ", value->asString());
+ }
+ state->AddErrorAtValue(errMsg, value);
+#endif
+ };
+};
+const auto INVALID_STRING = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ JsonErrors::EXPECTED_TYPE("a string")(value, state);
+};
+const auto INVALID_BOOL = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ JsonErrors::EXPECTED_TYPE("a bool")(value, state);
+};
+const auto INVALID_INT = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ JsonErrors::EXPECTED_TYPE("an integer")(value, state);
+};
+const auto INVALID_UINT = [](const Json::Value* value,
+ cmJSONState* state) -> void {
+ JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state);
+};
+const auto INVALID_NAMED_OBJECT =
+ [](const std::function<std::string(const Json::Value*, cmJSONState*)>&
+ nameGenerator) -> ObjectErrorGenerator {
+ return [nameGenerator](
+ ObjectError errorType,
+ const Json::Value::Members& extraFields) -> ErrorGenerator {
+ return [nameGenerator, errorType, extraFields](
+ const Json::Value* value, cmJSONState* state) -> void {
+#if !defined(CMAKE_BOOTSTRAP)
+ std::string name = nameGenerator(value, state);
+ switch (errorType) {
+ case ObjectError::RequiredMissing:
+ state->AddErrorAtValue(cmStrCat("Invalid Required ", name), value);
+ break;
+ case ObjectError::InvalidObject:
+ state->AddErrorAtValue(cmStrCat("Invalid ", name), value);
+ break;
+ case ObjectError::ExtraField: {
+ for (auto const& member : extraFields) {
+ if (value) {
+ state->AddErrorAtValue(
+ cmStrCat("Invalid extra field \"", member, "\" in ", name),
+ &(*value)[member]);
+ } else {
+ state->AddError(
+ cmStrCat("Invalid extra field \"", member, "\" in ", name));
+ }
+ }
+ } break;
+ case ObjectError::MissingRequired:
+ state->AddErrorAtValue(cmStrCat("Missing required field \"",
+ state->key(), "\" in ", name),
+ value);
+ break;
+ }
+#endif
+ };
+ };
+};
+const auto INVALID_OBJECT =
+ [](ObjectError errorType,
+ const Json::Value::Members& extraFields) -> ErrorGenerator {
+ return INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState*) -> std::string { return "Object"; })(
+ errorType, extraFields);
+};
+const auto INVALID_NAMED_OBJECT_KEY =
+ [](ObjectError errorType,
+ const Json::Value::Members& extraFields) -> ErrorGenerator {
+ return INVALID_NAMED_OBJECT(
+ [](const Json::Value*, cmJSONState* state) -> std::string {
+ for (auto it = state->parseStack.rbegin();
+ it != state->parseStack.rend(); ++it) {
+ if (it->first.rfind("$vector_item_", 0) == 0) {
+ continue;
+ }
+ return cmStrCat("\"", it->first, "\"");
+ }
+ return "root";
+ })(errorType, extraFields);
+};
+}
-template <typename E, typename... CallState>
struct cmJSONHelperBuilder
{
+
template <typename T>
class Object
{
public:
- Object(E&& success, E&& fail, bool allowExtra = true)
- : Success(std::move(success))
- , Fail(std::move(fail))
+ Object(JsonErrors::ObjectErrorGenerator error = JsonErrors::INVALID_OBJECT,
+ bool allowExtra = true)
+ : Error(std::move(error))
, AllowExtra(allowExtra)
{
}
@@ -38,8 +150,8 @@ struct cmJSONHelperBuilder
{
return this->BindPrivate(
name,
- [func, member](T& out, const Json::Value* value, CallState&&... state)
- -> E { return func(out.*member, value, std::forward(state)...); },
+ [func, member](T& out, const Json::Value* value, cmJSONState* state)
+ -> bool { return func(out.*member, value, state); },
required);
}
template <typename M, typename F>
@@ -49,9 +161,9 @@ struct cmJSONHelperBuilder
return this->BindPrivate(
name,
[func](T& /*out*/, const Json::Value* value,
- CallState&&... state) -> E {
+ cmJSONState* state) -> bool {
M dummy;
- return func(dummy, value, std::forward(state)...);
+ return func(dummy, value, state);
},
required);
}
@@ -61,46 +173,56 @@ struct cmJSONHelperBuilder
return this->BindPrivate(name, MemberFunction(func), required);
}
- E operator()(T& out, const Json::Value* value, CallState&&... state) const
+ bool operator()(T& out, const Json::Value* value, cmJSONState* state) const
{
+ Json::Value::Members extraFields;
+ bool success = true;
if (!value && this->AnyRequired) {
- return this->Fail;
+ Error(JsonErrors::ObjectError::RequiredMissing, extraFields)(value,
+ state);
+ return false;
}
if (value && !value->isObject()) {
- return this->Fail;
+ Error(JsonErrors::ObjectError::InvalidObject, extraFields)(value,
+ state);
+ return false;
}
- Json::Value::Members extraFields;
if (value) {
extraFields = value->getMemberNames();
}
for (auto const& m : this->Members) {
std::string name(m.Name.data(), m.Name.size());
+ state->push_stack(name, value);
if (value && value->isMember(name)) {
- E result = m.Function(out, &(*value)[name], std::forward(state)...);
- if (result != this->Success) {
- return result;
+ if (!m.Function(out, &(*value)[name], state)) {
+ success = false;
}
extraFields.erase(
std::find(extraFields.begin(), extraFields.end(), name));
} else if (!m.Required) {
- E result = m.Function(out, nullptr, std::forward(state)...);
- if (result != this->Success) {
- return result;
+ if (!m.Function(out, nullptr, state)) {
+ success = false;
}
} else {
- return this->Fail;
+ Error(JsonErrors::ObjectError::MissingRequired, extraFields)(value,
+ state);
+ success = false;
}
+ state->pop_stack();
}
- return this->AllowExtra || extraFields.empty() ? this->Success
- : this->Fail;
+ if (!this->AllowExtra && !extraFields.empty()) {
+ Error(JsonErrors::ObjectError::ExtraField, extraFields)(value, state);
+ success = false;
+ }
+ return success;
}
private:
// Not a true cmJSONHelper, it just happens to match the signature
- using MemberFunction =
- std::function<E(T& out, const Json::Value* value, CallState&&... state)>;
+ using MemberFunction = std::function<bool(T& out, const Json::Value* value,
+ cmJSONState* state)>;
struct Member
{
cm::string_view Name;
@@ -109,8 +231,7 @@ struct cmJSONHelperBuilder
};
std::vector<Member> Members;
bool AnyRequired = false;
- E Success;
- E Fail;
+ JsonErrors::ObjectErrorGenerator Error;
bool AllowExtra;
Object& BindPrivate(const cm::string_view& name, MemberFunction&& func,
@@ -127,175 +248,218 @@ struct cmJSONHelperBuilder
return *this;
}
};
- static cmJSONHelper<std::string, E, CallState...> String(
- E success, E fail, const std::string& defval = "")
+
+ static cmJSONHelper<std::string> String(
+ const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_STRING,
+ const std::string& defval = "")
{
- return [success, fail, defval](std::string& out, const Json::Value* value,
- CallState&&... /*state*/) -> E {
+ return [error, defval](std::string& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
out = defval;
- return success;
+ return true;
}
if (!value->isString()) {
- return fail;
+ error(value, state);
+ ;
+ return false;
}
out = value->asString();
- return success;
+ return true;
};
- }
+ };
+
+ static cmJSONHelper<std::string> String(const std::string& defval)
+ {
+ return String(JsonErrors::INVALID_STRING, defval);
+ };
- static cmJSONHelper<int, E, CallState...> Int(E success, E fail,
- int defval = 0)
+ static cmJSONHelper<int> Int(
+ const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_INT,
+ int defval = 0)
{
- return [success, fail, defval](int& out, const Json::Value* value,
- CallState&&... /*state*/) -> E {
+ return [error, defval](int& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
out = defval;
- return success;
+ return true;
}
if (!value->isInt()) {
- return fail;
+ error(value, state);
+ ;
+ return false;
}
out = value->asInt();
- return success;
+ return true;
};
}
- static cmJSONHelper<unsigned int, E, CallState...> UInt(
- E success, E fail, unsigned int defval = 0)
+ static cmJSONHelper<int> Int(int defval)
+ {
+ return Int(JsonErrors::INVALID_INT, defval);
+ };
+
+ static cmJSONHelper<unsigned int> UInt(
+ const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_UINT,
+ unsigned int defval = 0)
{
- return [success, fail, defval](unsigned int& out, const Json::Value* value,
- CallState&&... /*state*/) -> E {
+ return [error, defval](unsigned int& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
out = defval;
- return success;
+ return true;
}
if (!value->isUInt()) {
- return fail;
+ error(value, state);
+ ;
+ return false;
}
out = value->asUInt();
- return success;
+ return true;
};
}
- static cmJSONHelper<bool, E, CallState...> Bool(E success, E fail,
- bool defval = false)
+ static cmJSONHelper<unsigned int> UInt(unsigned int defval)
+ {
+ return UInt(JsonErrors::INVALID_UINT, defval);
+ }
+
+ static cmJSONHelper<bool> Bool(
+ const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_BOOL,
+ bool defval = false)
{
- return [success, fail, defval](bool& out, const Json::Value* value,
- CallState&&... /*state*/) -> E {
+ return [error, defval](bool& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
out = defval;
- return success;
+ return true;
}
if (!value->isBool()) {
- return fail;
+ error(value, state);
+ ;
+ return false;
}
out = value->asBool();
- return success;
+ return true;
};
}
+ static cmJSONHelper<bool> Bool(bool defval)
+ {
+ return Bool(JsonErrors::INVALID_BOOL, defval);
+ }
+
template <typename T, typename F, typename Filter>
- static cmJSONHelper<std::vector<T>, E, CallState...> VectorFilter(
- E success, E fail, F func, Filter filter)
+ static cmJSONHelper<std::vector<T>> VectorFilter(
+ const JsonErrors::ErrorGenerator& error, F func, Filter filter)
{
- return [success, fail, func, filter](std::vector<T>& out,
- const Json::Value* value,
- CallState&&... state) -> E {
+ return [error, func, filter](std::vector<T>& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
+ bool success = true;
if (!value) {
out.clear();
- return success;
+ return true;
}
if (!value->isArray()) {
- return fail;
+ error(value, state);
+ return false;
}
out.clear();
+ int index = 0;
for (auto const& item : *value) {
+ state->push_stack(cmStrCat("$vector_item_", index++), &item);
T t;
- E result = func(t, &item, std::forward(state)...);
- if (result != success) {
- return result;
+ if (!func(t, &item, state)) {
+ success = false;
}
if (!filter(t)) {
+ state->pop_stack();
continue;
}
out.push_back(std::move(t));
+ state->pop_stack();
}
return success;
};
}
template <typename T, typename F>
- static cmJSONHelper<std::vector<T>, E, CallState...> Vector(E success,
- E fail, F func)
+ static cmJSONHelper<std::vector<T>> Vector(JsonErrors::ErrorGenerator error,
+ F func)
{
- return VectorFilter<T, F>(success, fail, func,
+ return VectorFilter<T, F>(std::move(error), func,
[](const T&) { return true; });
}
template <typename T, typename F, typename Filter>
- static cmJSONHelper<std::map<std::string, T>, E, CallState...> MapFilter(
- E success, E fail, F func, Filter filter)
+ static cmJSONHelper<std::map<std::string, T>> MapFilter(
+ const JsonErrors::ErrorGenerator& error, F func, Filter filter)
{
- return [success, fail, func, filter](std::map<std::string, T>& out,
- const Json::Value* value,
- CallState&&... state) -> E {
+ return [error, func, filter](std::map<std::string, T>& out,
+ const Json::Value* value,
+ cmJSONState* state) -> bool {
+ bool success = true;
if (!value) {
out.clear();
- return success;
+ return true;
}
if (!value->isObject()) {
- return fail;
+ error(value, state);
+ ;
+ return false;
}
out.clear();
for (auto const& key : value->getMemberNames()) {
+ state->push_stack(cmStrCat(key, ""), &(*value)[key]);
if (!filter(key)) {
+ state->pop_stack();
continue;
}
T t;
- E result = func(t, &(*value)[key], std::forward(state)...);
- if (result != success) {
- return result;
+ if (!func(t, &(*value)[key], state)) {
+ success = false;
}
out[key] = std::move(t);
+ state->pop_stack();
}
return success;
};
}
template <typename T, typename F>
- static cmJSONHelper<std::map<std::string, T>, E, CallState...> Map(E success,
- E fail,
- F func)
+ static cmJSONHelper<std::map<std::string, T>> Map(
+ const JsonErrors::ErrorGenerator& error, F func)
{
- return MapFilter<T, F>(success, fail, func,
+ return MapFilter<T, F>(error, func,
[](const std::string&) { return true; });
}
template <typename T, typename F>
- static cmJSONHelper<cm::optional<T>, E, CallState...> Optional(E success,
- F func)
+ static cmJSONHelper<cm::optional<T>> Optional(F func)
{
- return [success, func](cm::optional<T>& out, const Json::Value* value,
- CallState&&... state) -> E {
+ return [func](cm::optional<T>& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
out.reset();
- return success;
+ return true;
}
out.emplace();
- return func(*out, value, std::forward(state)...);
+ return func(*out, value, state);
};
}
template <typename T, typename F>
- static cmJSONHelper<T, E, CallState...> Required(E fail, F func)
+ static cmJSONHelper<T> Required(const JsonErrors::ErrorGenerator& error,
+ F func)
{
- return [fail, func](T& out, const Json::Value* value,
- CallState&&... state) -> E {
+ return [error, func](T& out, const Json::Value* value,
+ cmJSONState* state) -> bool {
if (!value) {
- return fail;
+ error(value, state);
+ ;
+ return false;
}
- return func(out, value, std::forward(state)...);
+ return func(out, value, state);
};
}
};
diff --git a/Source/cmJSONState.cxx b/Source/cmJSONState.cxx
new file mode 100644
index 0000000000..92bde778a7
--- /dev/null
+++ b/Source/cmJSONState.cxx
@@ -0,0 +1,163 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmJSONState.h"
+
+#include <sstream>
+
+#include <cm/memory>
+
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmStringAlgorithms.h"
+
+cmJSONState::cmJSONState(const std::string& filename, Json::Value* root)
+{
+ cmsys::ifstream fin(filename.c_str(), std::ios::in | std::ios::binary);
+ if (!fin) {
+ this->AddError(cmStrCat("File not found: ", filename));
+ return;
+ }
+ // If there's a BOM, toss it.
+ cmsys::FStream::ReadBOM(fin);
+
+ // Save the entire document.
+ std::streampos finBegin = fin.tellg();
+ this->doc = std::string(std::istreambuf_iterator<char>(fin),
+ std::istreambuf_iterator<char>());
+ if (this->doc.empty()) {
+ this->AddError("A JSON document cannot be empty");
+ return;
+ }
+ fin.seekg(finBegin);
+
+ // Parse the document.
+ Json::CharReaderBuilder builder;
+ Json::CharReaderBuilder::strictMode(&builder.settings_);
+ std::string errMsg;
+ if (!Json::parseFromStream(builder, fin, root, &errMsg)) {
+ errMsg = cmStrCat("JSON Parse Error: ", filename, ":\n", errMsg);
+ this->AddError(errMsg);
+ }
+}
+
+void cmJSONState::AddError(std::string const& errMsg)
+{
+ this->errors.push_back(Error(errMsg));
+}
+
+void cmJSONState::AddErrorAtValue(std::string const& errMsg,
+ const Json::Value* value)
+{
+ if (value && !value->isNull()) {
+ this->AddErrorAtOffset(errMsg, value->getOffsetStart());
+ } else {
+ this->AddError(errMsg);
+ }
+}
+
+void cmJSONState::AddErrorAtOffset(std::string const& errMsg,
+ std::ptrdiff_t offset)
+{
+ if (doc.empty()) {
+ this->AddError(errMsg);
+ } else {
+ Location loc = LocateInDocument(offset);
+ this->errors.push_back(Error(loc, errMsg));
+ }
+}
+
+std::string cmJSONState::GetErrorMessage(bool showContext)
+{
+ std::string message;
+ for (auto const& error : this->errors) {
+ message = cmStrCat(message, error.GetErrorMessage(), "\n");
+ if (showContext) {
+ Location loc = error.GetLocation();
+ if (loc.column > 0) {
+ message = cmStrCat(message, GetJsonContext(loc), "\n");
+ }
+ }
+ }
+ message = cmStrCat("\n", message);
+ message.pop_back();
+ return message;
+}
+
+std::string cmJSONState::key()
+{
+ if (!this->parseStack.empty()) {
+ return this->parseStack.back().first;
+ }
+ return "";
+}
+
+std::string cmJSONState::key_after(std::string const& k)
+{
+ for (auto it = this->parseStack.begin(); it != this->parseStack.end();
+ ++it) {
+ if (it->first == k && (++it) != this->parseStack.end()) {
+ return it->first;
+ }
+ }
+ return "";
+}
+
+const Json::Value* cmJSONState::value_after(std::string const& k)
+{
+ for (auto it = this->parseStack.begin(); it != this->parseStack.end();
+ ++it) {
+ if (it->first == k && (++it) != this->parseStack.end()) {
+ return it->second;
+ }
+ }
+ return nullptr;
+}
+
+void cmJSONState::push_stack(std::string const& k, const Json::Value* value)
+{
+ this->parseStack.push_back(JsonPair(k, value));
+}
+
+void cmJSONState::pop_stack()
+{
+ this->parseStack.pop_back();
+}
+
+std::string cmJSONState::GetJsonContext(Location loc)
+{
+ std::string line;
+ std::stringstream sstream(doc);
+ for (int i = 0; i < loc.line; ++i) {
+ std::getline(sstream, line, '\n');
+ }
+ return cmStrCat(line, '\n', std::string(loc.column - 1, ' '), '^');
+}
+
+cmJSONState::Location cmJSONState::LocateInDocument(ptrdiff_t offset)
+{
+ int line = 1;
+ int col = 1;
+ const char* beginDoc = doc.data();
+ const char* last = beginDoc + offset;
+ for (; beginDoc != last; ++beginDoc) {
+ switch (*beginDoc) {
+ case '\r':
+ if (beginDoc + 1 != last && beginDoc[1] == '\n') {
+ continue; // consume CRLF as a single token.
+ }
+ CM_FALLTHROUGH; // CR without a following LF is same as LF
+ case '\n':
+ col = 1;
+ ++line;
+ break;
+ default:
+ ++col;
+ break;
+ }
+ }
+ return { line, col };
+}
diff --git a/Source/cmJSONState.h b/Source/cmJSONState.h
new file mode 100644
index 0000000000..4984c81b34
--- /dev/null
+++ b/Source/cmJSONState.h
@@ -0,0 +1,73 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <cstddef>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "cmJSONState.h"
+#include "cmStringAlgorithms.h"
+
+namespace Json {
+class Value;
+}
+
+class cmJSONState
+{
+ using Location = struct
+ {
+ int line;
+ int column;
+ };
+
+public:
+ using JsonPair = std::pair<const std::string, const Json::Value*>;
+ cmJSONState() = default;
+ cmJSONState(const std::string& filename, Json::Value* root);
+ void AddError(std::string const& errMsg);
+ void AddErrorAtValue(std::string const& errMsg, const Json::Value* value);
+ void AddErrorAtOffset(std::string const& errMsg, std::ptrdiff_t offset);
+ std::string GetErrorMessage(bool showContext = true);
+ std::string key();
+ std::string key_after(std::string const& key);
+ const Json::Value* value_after(std::string const& key);
+ void push_stack(std::string const& key, const Json::Value* value);
+ void pop_stack();
+
+ class Error
+ {
+ public:
+ Error(Location loc, std::string errMsg)
+ : location(loc)
+ , message(std::move(errMsg)){};
+ Error(std::string errMsg)
+ : location({ -1, -1 })
+ , message(std::move(errMsg)){};
+ std::string GetErrorMessage() const
+ {
+ std::string output = message;
+ if (location.line > 0) {
+ output = cmStrCat("Error: @", location.line, ",", location.column,
+ ": ", output);
+ }
+ return output;
+ }
+ Location GetLocation() const { return location; }
+
+ private:
+ Location location;
+ std::string message;
+ };
+
+ std::vector<JsonPair> parseStack;
+ std::vector<Error> errors;
+ std::string doc;
+
+private:
+ std::string GetJsonContext(Location loc);
+ Location LocateInDocument(ptrdiff_t offset);
+};
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index d4bbc148d6..f943415800 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -52,6 +52,7 @@
#if !defined(CMAKE_BOOTSTRAP)
# include "cmMakefileProfilingData.h"
#endif
+#include "cmJSONState.h"
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -1411,13 +1412,10 @@ void cmake::SetArgs(const std::vector<std::string>& args)
if (listPresets != ListPresets::None || !presetName.empty()) {
cmCMakePresetsGraph presetsGraph;
auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory());
- if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
+ if (result != true) {
std::string errorMsg =
- cmStrCat("Could not read presets from ", this->GetHomeDirectory(),
- ": ", cmCMakePresetsGraph::ResultToString(result));
- if (!presetsGraph.errors.empty()) {
- errorMsg = cmStrCat(errorMsg, "\nErrors:\n", presetsGraph.errors);
- }
+ cmStrCat("Could not read presets from ", this->GetHomeDirectory(), ":",
+ presetsGraph.parseState.GetErrorMessage());
cmSystemTools::Error(errorMsg);
return;
}
@@ -3426,10 +3424,10 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
cmCMakePresetsGraph settingsFile;
auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());
- if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
+ if (result != true) {
cmSystemTools::Error(
- cmStrCat("Could not read presets from ", this->GetHomeDirectory(),
- ": ", cmCMakePresetsGraph::ResultToString(result)));
+ cmStrCat("Could not read presets from ", this->GetHomeDirectory(), ":",
+ settingsFile.parseState.GetErrorMessage()));
return 1;
}
@@ -3782,10 +3780,10 @@ int cmake::Workflow(const std::string& presetName,
cmCMakePresetsGraph settingsFile;
auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());
- if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
- cmSystemTools::Error(
- cmStrCat("Could not read presets from ", this->GetHomeDirectory(), ": ",
- cmCMakePresetsGraph::ResultToString(result)));
+ if (result != true) {
+ cmSystemTools::Error(cmStrCat("Could not read presets from ",
+ this->GetHomeDirectory(), ":",
+ settingsFile.parseState.GetErrorMessage()));
return 1;
}
diff --git a/Tests/CMakeLib/testCTestResourceAllocator.cxx b/Tests/CMakeLib/testCTestResourceAllocator.cxx
index 72e06e5d40..3a2e524c9b 100644
--- a/Tests/CMakeLib/testCTestResourceAllocator.cxx
+++ b/Tests/CMakeLib/testCTestResourceAllocator.cxx
@@ -5,12 +5,16 @@
#include "cmCTestResourceAllocator.h"
#include "cmCTestResourceSpec.h"
-
-static const cmCTestResourceSpec spec{ { {
- /* clang-format off */
- { "gpus", { { "0", 4 }, { "1", 8 }, { "2", 0 }, { "3", 8 } } },
- /* clang-format on */
-} } };
+#include "cmJSONState.h"
+
+static const cmCTestResourceSpec spec{
+ { {
+ /* clang-format off */
+ { "gpus", { { "0", 4 }, { "1", 8 }, { "2", 0 }, { "3", 8 } }, },
+ /* clang-format on */
+ } },
+ cmJSONState()
+};
static bool testInitializeFromResourceSpec()
{
diff --git a/Tests/CMakeLib/testCTestResourceSpec.cxx b/Tests/CMakeLib/testCTestResourceSpec.cxx
index b49f8ff2b4..4a0021f711 100644
--- a/Tests/CMakeLib/testCTestResourceSpec.cxx
+++ b/Tests/CMakeLib/testCTestResourceSpec.cxx
@@ -3,89 +3,72 @@
#include <vector>
#include "cmCTestResourceSpec.h"
+#include "cmJSONState.h"
struct ExpectedSpec
{
std::string Path;
- cmCTestResourceSpec::ReadFileResult ParseResult;
+ bool ParseResult;
cmCTestResourceSpec Expected;
};
static const std::vector<ExpectedSpec> expectedResourceSpecs = {
{ "spec1.json",
- cmCTestResourceSpec::ReadFileResult::READ_OK,
+ true,
{ { {
- { "gpus",
- {
- { "2", 4 },
- { "e", 1 },
- } },
- { "threads", {} },
- } } } },
- { "spec2.json", cmCTestResourceSpec::ReadFileResult::READ_OK, {} },
- { "spec3.json",
- cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC,
- {} },
- { "spec4.json",
- cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC,
- {} },
- { "spec5.json",
- cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC,
- {} },
- { "spec6.json",
- cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC,
- {} },
- { "spec7.json",
- cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE_TYPE,
- {} },
- { "spec8.json", cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, {} },
- { "spec9.json", cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, {} },
- { "spec10.json", cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, {} },
- { "spec11.json", cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, {} },
- { "spec12.json", cmCTestResourceSpec::ReadFileResult::INVALID_ROOT, {} },
- { "spec13.json", cmCTestResourceSpec::ReadFileResult::JSON_PARSE_ERROR, {} },
- { "spec14.json", cmCTestResourceSpec::ReadFileResult::READ_OK, {} },
- { "spec15.json", cmCTestResourceSpec::ReadFileResult::READ_OK, {} },
- { "spec16.json", cmCTestResourceSpec::ReadFileResult::READ_OK, {} },
- { "spec17.json", cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, {} },
- { "spec18.json", cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, {} },
- { "spec19.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec20.json", cmCTestResourceSpec::ReadFileResult::READ_OK, {} },
- { "spec21.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec22.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec23.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec24.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec25.json",
- cmCTestResourceSpec::ReadFileResult::UNSUPPORTED_VERSION,
- {} },
- { "spec26.json",
- cmCTestResourceSpec::ReadFileResult::UNSUPPORTED_VERSION,
- {} },
- { "spec27.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec28.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec29.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec30.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec31.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec32.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec33.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec34.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec35.json", cmCTestResourceSpec::ReadFileResult::INVALID_VERSION, {} },
- { "spec36.json", cmCTestResourceSpec::ReadFileResult::NO_VERSION, {} },
- { "noexist.json", cmCTestResourceSpec::ReadFileResult::FILE_NOT_FOUND, {} },
+ { "gpus",
+ {
+ { "2", 4 },
+ { "e", 1 },
+ } },
+ { "threads", {} },
+ } },
+ cmJSONState() } },
+ { "spec2.json", true, {} },
+ { "spec3.json", false, {} },
+ { "spec4.json", false, {} },
+ { "spec5.json", false, {} },
+ { "spec6.json", false, {} },
+ { "spec7.json", false, {} },
+ { "spec8.json", false, {} },
+ { "spec9.json", false, {} },
+ { "spec10.json", false, {} },
+ { "spec11.json", false, {} },
+ { "spec12.json", false, {} },
+ { "spec13.json", false, {} },
+ { "spec14.json", true, {} },
+ { "spec15.json", true, {} },
+ { "spec16.json", true, {} },
+ { "spec17.json", false, {} },
+ { "spec18.json", false, {} },
+ { "spec19.json", false, {} },
+ { "spec20.json", true, {} },
+ { "spec21.json", false, {} },
+ { "spec22.json", false, {} },
+ { "spec23.json", false, {} },
+ { "spec24.json", false, {} },
+ { "spec25.json", false, {} },
+ { "spec26.json", false, {} },
+ { "spec27.json", false, {} },
+ { "spec28.json", false, {} },
+ { "spec29.json", false, {} },
+ { "spec30.json", false, {} },
+ { "spec31.json", false, {} },
+ { "spec32.json", false, {} },
+ { "spec33.json", false, {} },
+ { "spec34.json", false, {} },
+ { "spec35.json", false, {} },
+ { "spec36.json", false, {} },
+ { "noexist.json", false, {} },
};
-static bool testSpec(const std::string& path,
- cmCTestResourceSpec::ReadFileResult expectedResult,
+static bool testSpec(const std::string& path, bool expectedResult,
const cmCTestResourceSpec& expected)
{
cmCTestResourceSpec actual;
auto result = actual.ReadFromJSONFile(path);
if (result != expectedResult) {
- std::cout << "ReadFromJSONFile(\"" << path << "\") returned \""
- << cmCTestResourceSpec::ResultToString(result)
- << "\", should be \""
- << cmCTestResourceSpec::ResultToString(expectedResult) << "\""
- << std::endl;
+ std::cout << "ReadFromJSONFile(\"" << path << "\") failed \"" << std::endl;
return false;
}
diff --git a/Tests/CMakeLib/testJSONHelpers.cxx b/Tests/CMakeLib/testJSONHelpers.cxx
index 053c163ec9..50f0386567 100644
--- a/Tests/CMakeLib/testJSONHelpers.cxx
+++ b/Tests/CMakeLib/testJSONHelpers.cxx
@@ -10,6 +10,7 @@
#include <cm3p/json/value.h>
#include "cmJSONHelpers.h"
+#include "cmJSONState.h"
#define ASSERT_TRUE(x) \
do { \
@@ -31,59 +32,65 @@ struct InheritedStruct : public ObjectStruct
std::string Field3;
};
-enum class ErrorCode
+namespace ErrorMessages {
+using ErrorGenerator =
+ std::function<void(const Json::Value*, cmJSONState* state)>;
+ErrorGenerator ErrorGeneratorBuilder(std::string errorMessage)
{
- Success,
- InvalidInt,
- InvalidBool,
- InvalidString,
- InvalidSubObject,
- InvalidObject,
- InvalidArray,
- MissingRequired,
+ return [errorMessage](const Json::Value* value, cmJSONState* state) -> void {
+ state->AddErrorAtValue(errorMessage, value);
+ };
+};
+ErrorGenerator InvalidArray = ErrorGeneratorBuilder("Invalid Array");
+ErrorGenerator MissingRequired = ErrorGeneratorBuilder("Missing Required");
+ErrorGenerator InvalidMap = ErrorGeneratorBuilder("Invalid Map");
+ErrorGenerator InvalidObject(JsonErrors::ObjectError /*errorType*/,
+ const Json::Value::Members& extraFields)
+{
+ return [extraFields](const Json::Value* value, cmJSONState* state) -> void {
+ state->AddErrorAtValue("Invalid Object", value);
+ };
+};
};
-using JSONHelperBuilder = cmJSONHelperBuilder<ErrorCode>;
+using JSONHelperBuilder = cmJSONHelperBuilder;
-auto const IntHelper =
- JSONHelperBuilder::Int(ErrorCode::Success, ErrorCode::InvalidInt, 1);
+auto const IntHelper = JSONHelperBuilder::Int(1);
auto const RequiredIntHelper =
- JSONHelperBuilder::Required<int>(ErrorCode::MissingRequired, IntHelper);
-auto const UIntHelper =
- JSONHelperBuilder::UInt(ErrorCode::Success, ErrorCode::InvalidInt, 1);
-auto const BoolHelper =
- JSONHelperBuilder::Bool(ErrorCode::Success, ErrorCode::InvalidBool, false);
-auto const StringHelper = JSONHelperBuilder::String(
- ErrorCode::Success, ErrorCode::InvalidString, "default");
+ JSONHelperBuilder::Required<int>(ErrorMessages::MissingRequired, IntHelper);
+auto const UIntHelper = JSONHelperBuilder::UInt(1);
+auto const BoolHelper = JSONHelperBuilder::Bool(false);
+auto const StringHelper = JSONHelperBuilder::String("default");
auto const RequiredStringHelper = JSONHelperBuilder::Required<std::string>(
- ErrorCode::MissingRequired, StringHelper);
+ ErrorMessages::MissingRequired, StringHelper);
auto const StringVectorHelper = JSONHelperBuilder::Vector<std::string>(
- ErrorCode::Success, ErrorCode::InvalidArray, StringHelper);
+ ErrorMessages::InvalidArray, StringHelper);
auto const StringVectorFilterHelper =
JSONHelperBuilder::VectorFilter<std::string>(
- ErrorCode::Success, ErrorCode::InvalidArray, StringHelper,
+ ErrorMessages::InvalidArray, StringHelper,
[](const std::string& value) { return value != "ignore"; });
-auto const StringMapHelper = JSONHelperBuilder::Map<std::string>(
- ErrorCode::Success, ErrorCode::InvalidObject, StringHelper);
+auto const StringMapHelper =
+ JSONHelperBuilder::Map<std::string>(ErrorMessages::InvalidMap, StringHelper);
auto const StringMapFilterHelper = JSONHelperBuilder::MapFilter<std::string>(
- ErrorCode::Success, ErrorCode::InvalidObject, StringHelper,
+ ErrorMessages::InvalidMap, StringHelper,
[](const std::string& key) { return key != "ignore"; });
auto const OptionalStringHelper =
- JSONHelperBuilder::Optional<std::string>(ErrorCode::Success, StringHelper);
+ JSONHelperBuilder::Optional<std::string>(StringHelper);
bool testInt()
{
Json::Value v(2);
+ cmJSONState state;
int i = 0;
- ASSERT_TRUE(IntHelper(i, &v) == ErrorCode::Success);
+ ASSERT_TRUE(IntHelper(i, &v, &state));
ASSERT_TRUE(i == 2);
i = 0;
v = Json::nullValue;
- ASSERT_TRUE(IntHelper(i, &v) == ErrorCode::InvalidInt);
+ ASSERT_TRUE(!IntHelper(i, &v, &state));
i = 0;
- ASSERT_TRUE(IntHelper(i, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(IntHelper(i, nullptr, &state));
ASSERT_TRUE(i == 1);
return true;
@@ -92,16 +99,16 @@ bool testInt()
bool testUInt()
{
Json::Value v(2);
+ cmJSONState state;
unsigned int i = 0;
- ASSERT_TRUE(UIntHelper(i, &v) == ErrorCode::Success);
+ ASSERT_TRUE(UIntHelper(i, &v, &state));
ASSERT_TRUE(i == 2);
-
i = 0;
v = Json::nullValue;
- ASSERT_TRUE(UIntHelper(i, &v) == ErrorCode::InvalidInt);
+ ASSERT_TRUE(!UIntHelper(i, &v, &state));
i = 0;
- ASSERT_TRUE(UIntHelper(i, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(UIntHelper(i, nullptr, &state));
ASSERT_TRUE(i == 1);
return true;
@@ -110,21 +117,22 @@ bool testUInt()
bool testBool()
{
Json::Value v(true);
+ cmJSONState state;
bool b = false;
- ASSERT_TRUE(BoolHelper(b, &v) == ErrorCode::Success);
+ ASSERT_TRUE(BoolHelper(b, &v, &state));
ASSERT_TRUE(b);
b = false;
v = false;
- ASSERT_TRUE(BoolHelper(b, &v) == ErrorCode::Success);
+ ASSERT_TRUE(BoolHelper(b, &v, &state));
ASSERT_TRUE(!b);
b = false;
v = 4;
- ASSERT_TRUE(BoolHelper(b, &v) == ErrorCode::InvalidBool);
+ ASSERT_TRUE(!BoolHelper(b, &v, &state));
b = true;
- ASSERT_TRUE(BoolHelper(b, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(BoolHelper(b, nullptr, &state));
ASSERT_TRUE(!b);
return true;
@@ -133,16 +141,17 @@ bool testBool()
bool testString()
{
Json::Value v("str");
+ cmJSONState state;
std::string str = "";
- ASSERT_TRUE(StringHelper(str, &v) == ErrorCode::Success);
+ ASSERT_TRUE(StringHelper(str, &v, &state));
ASSERT_TRUE(str == "str");
str = "";
v = Json::nullValue;
- ASSERT_TRUE(StringHelper(str, &v) == ErrorCode::InvalidString);
+ ASSERT_TRUE(!StringHelper(str, &v, &state));
str = "";
- ASSERT_TRUE(StringHelper(str, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(StringHelper(str, nullptr, &state));
ASSERT_TRUE(str == "default");
return true;
@@ -150,17 +159,15 @@ bool testString()
bool testObject()
{
- auto const subhelper =
- JSONHelperBuilder::Object<ObjectStruct>(ErrorCode::Success,
- ErrorCode::InvalidSubObject)
- .Bind("subfield"_s, &ObjectStruct::Field2, IntHelper);
- auto const helper = JSONHelperBuilder::Object<ObjectStruct>(
- ErrorCode::Success, ErrorCode::InvalidObject)
+ auto const subhelper = JSONHelperBuilder::Object<ObjectStruct>().Bind(
+ "subfield"_s, &ObjectStruct::Field2, IntHelper);
+ auto const helper = JSONHelperBuilder::Object<ObjectStruct>()
.Bind("field1"_s, &ObjectStruct::Field1, StringHelper)
.Bind("field2"_s, subhelper)
.Bind<std::string>("field3"_s, nullptr, StringHelper);
Json::Value v(Json::objectValue);
+ cmJSONState state;
v["field1"] = "Hello";
v["field2"] = Json::objectValue;
v["field2"]["subfield"] = 2;
@@ -168,38 +175,38 @@ bool testObject()
v["extra"] = "extra";
ObjectStruct s1;
- ASSERT_TRUE(helper(s1, &v) == ErrorCode::Success);
+ ASSERT_TRUE(helper(s1, &v, &state));
ASSERT_TRUE(s1.Field1 == "Hello");
ASSERT_TRUE(s1.Field2 == 2);
v["field2"]["subfield"] = "wrong";
ObjectStruct s2;
- ASSERT_TRUE(helper(s2, &v) == ErrorCode::InvalidInt);
+ ASSERT_TRUE(!helper(s2, &v, &state));
v["field2"].removeMember("subfield");
ObjectStruct s3;
- ASSERT_TRUE(helper(s3, &v) == ErrorCode::InvalidSubObject);
+ ASSERT_TRUE(!helper(s3, &v, &state));
v.removeMember("field2");
ObjectStruct s4;
- ASSERT_TRUE(helper(s4, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s4, &v, &state));
v["field2"] = Json::objectValue;
v["field2"]["subfield"] = 2;
v["field3"] = 3;
ObjectStruct s5;
- ASSERT_TRUE(helper(s5, &v) == ErrorCode::InvalidString);
+ ASSERT_TRUE(!helper(s5, &v, &state));
v.removeMember("field3");
ObjectStruct s6;
- ASSERT_TRUE(helper(s6, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s6, &v, &state));
v = "Hello";
ObjectStruct s7;
- ASSERT_TRUE(helper(s7, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s7, &v, &state));
ObjectStruct s8;
- ASSERT_TRUE(helper(s8, nullptr) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s8, nullptr, &state));
return true;
}
@@ -207,47 +214,48 @@ bool testObject()
bool testObjectInherited()
{
auto const helper =
- JSONHelperBuilder::Object<InheritedStruct>(ErrorCode::Success,
- ErrorCode::InvalidObject)
+ JSONHelperBuilder::Object<InheritedStruct>(ErrorMessages::InvalidObject,
+ true)
.Bind("field1"_s, &InheritedStruct::Field1, StringHelper)
.Bind("field2"_s, &InheritedStruct::Field2, IntHelper)
.Bind("field3"_s, &InheritedStruct::Field3, StringHelper);
Json::Value v(Json::objectValue);
+ cmJSONState state;
v["field1"] = "Hello";
v["field2"] = 2;
v["field3"] = "world!";
v["extra"] = "extra";
InheritedStruct s1;
- ASSERT_TRUE(helper(s1, &v) == ErrorCode::Success);
+ ASSERT_TRUE(helper(s1, &v, &state));
ASSERT_TRUE(s1.Field1 == "Hello");
ASSERT_TRUE(s1.Field2 == 2);
ASSERT_TRUE(s1.Field3 == "world!");
v["field2"] = "wrong";
InheritedStruct s2;
- ASSERT_TRUE(helper(s2, &v) == ErrorCode::InvalidInt);
+ ASSERT_TRUE(!helper(s2, &v, &state));
v.removeMember("field2");
InheritedStruct s3;
- ASSERT_TRUE(helper(s3, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s3, &v, &state));
v["field2"] = 2;
v["field3"] = 3;
InheritedStruct s4;
- ASSERT_TRUE(helper(s4, &v) == ErrorCode::InvalidString);
+ ASSERT_TRUE(!helper(s4, &v, &state));
v.removeMember("field3");
InheritedStruct s5;
- ASSERT_TRUE(helper(s5, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s5, &v, &state));
v = "Hello";
InheritedStruct s6;
- ASSERT_TRUE(helper(s6, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s6, &v, &state));
InheritedStruct s7;
- ASSERT_TRUE(helper(s7, nullptr) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s7, nullptr, &state));
return true;
}
@@ -255,22 +263,23 @@ bool testObjectInherited()
bool testObjectNoExtra()
{
auto const helper = JSONHelperBuilder::Object<ObjectStruct>(
- ErrorCode::Success, ErrorCode::InvalidObject, false)
+ ErrorMessages::InvalidObject, false)
.Bind("field1"_s, &ObjectStruct::Field1, StringHelper)
.Bind("field2"_s, &ObjectStruct::Field2, IntHelper);
Json::Value v(Json::objectValue);
+ cmJSONState state;
v["field1"] = "Hello";
v["field2"] = 2;
ObjectStruct s1;
- ASSERT_TRUE(helper(s1, &v) == ErrorCode::Success);
+ ASSERT_TRUE(helper(s1, &v, &state));
ASSERT_TRUE(s1.Field1 == "Hello");
ASSERT_TRUE(s1.Field2 == 2);
v["extra"] = "world!";
ObjectStruct s2;
- ASSERT_TRUE(helper(s2, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!helper(s2, &v, &state));
return true;
}
@@ -278,31 +287,31 @@ bool testObjectNoExtra()
bool testObjectOptional()
{
auto const helper =
- JSONHelperBuilder::Object<ObjectStruct>(ErrorCode::Success,
- ErrorCode::InvalidObject)
+ JSONHelperBuilder::Object<ObjectStruct>(ErrorMessages::InvalidObject, true)
.Bind("field1"_s, &ObjectStruct::Field1, StringHelper, false)
.Bind("field2"_s, &ObjectStruct::Field2, IntHelper, false)
.Bind<std::string>("field3_s", nullptr, StringHelper, false);
Json::Value v(Json::objectValue);
+ cmJSONState state;
v["field1"] = "Hello";
v["field2"] = 2;
v["field3"] = "world!";
v["extra"] = "extra";
ObjectStruct s1;
- ASSERT_TRUE(helper(s1, &v) == ErrorCode::Success);
+ ASSERT_TRUE(helper(s1, &v, &state));
ASSERT_TRUE(s1.Field1 == "Hello");
ASSERT_TRUE(s1.Field2 == 2);
v = Json::objectValue;
ObjectStruct s2;
- ASSERT_TRUE(helper(s2, &v) == ErrorCode::Success);
+ ASSERT_TRUE(helper(s2, &v, &state));
ASSERT_TRUE(s2.Field1 == "default");
ASSERT_TRUE(s2.Field2 == 1);
ObjectStruct s3;
- ASSERT_TRUE(helper(s3, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(helper(s3, nullptr, &state));
ASSERT_TRUE(s3.Field1 == "default");
ASSERT_TRUE(s3.Field2 == 1);
@@ -312,25 +321,26 @@ bool testObjectOptional()
bool testVector()
{
Json::Value v(Json::arrayValue);
+ cmJSONState state;
v.append("Hello");
v.append("world!");
v.append("ignore");
std::vector<std::string> l{ "default" };
std::vector<std::string> expected{ "Hello", "world!", "ignore" };
- ASSERT_TRUE(StringVectorHelper(l, &v) == ErrorCode::Success);
+ ASSERT_TRUE(StringVectorHelper(l, &v, &state));
ASSERT_TRUE(l == expected);
v[1] = 2;
l = { "default" };
- ASSERT_TRUE(StringVectorHelper(l, &v) == ErrorCode::InvalidString);
+ ASSERT_TRUE(!StringVectorHelper(l, &v, &state));
v = "Hello";
l = { "default" };
- ASSERT_TRUE(StringVectorHelper(l, &v) == ErrorCode::InvalidArray);
+ ASSERT_TRUE(!StringVectorHelper(l, &v, &state));
l = { "default" };
- ASSERT_TRUE(StringVectorHelper(l, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(StringVectorHelper(l, nullptr, &state));
ASSERT_TRUE(l.empty());
return true;
@@ -339,6 +349,7 @@ bool testVector()
bool testVectorFilter()
{
Json::Value v(Json::arrayValue);
+ cmJSONState state;
v.append("Hello");
v.append("world!");
v.append("ignore");
@@ -348,19 +359,19 @@ bool testVectorFilter()
"Hello",
"world!",
};
- ASSERT_TRUE(StringVectorFilterHelper(l, &v) == ErrorCode::Success);
+ ASSERT_TRUE(StringVectorFilterHelper(l, &v, &state));
ASSERT_TRUE(l == expected);
v[1] = 2;
l = { "default" };
- ASSERT_TRUE(StringVectorFilterHelper(l, &v) == ErrorCode::InvalidString);
+ ASSERT_TRUE(!StringVectorFilterHelper(l, &v, &state));
v = "Hello";
l = { "default" };
- ASSERT_TRUE(StringVectorFilterHelper(l, &v) == ErrorCode::InvalidArray);
+ ASSERT_TRUE(!StringVectorFilterHelper(l, &v, &state));
l = { "default" };
- ASSERT_TRUE(StringVectorFilterHelper(l, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(StringVectorFilterHelper(l, nullptr, &state));
ASSERT_TRUE(l.empty());
return true;
@@ -372,20 +383,21 @@ bool testMap()
v["field1"] = "Hello";
v["field2"] = "world!";
v["ignore"] = "ignore";
+ cmJSONState state;
std::map<std::string, std::string> m{ { "key", "default" } };
std::map<std::string, std::string> expected{ { "field1", "Hello" },
{ "field2", "world!" },
{ "ignore", "ignore" } };
- ASSERT_TRUE(StringMapHelper(m, &v) == ErrorCode::Success);
+ ASSERT_TRUE(StringMapHelper(m, &v, &state));
ASSERT_TRUE(m == expected);
v = Json::arrayValue;
m = { { "key", "default" } };
- ASSERT_TRUE(StringMapHelper(m, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!StringMapHelper(m, &v, &state));
m = { { "key", "default" } };
- ASSERT_TRUE(StringMapHelper(m, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(StringMapHelper(m, nullptr, &state));
ASSERT_TRUE(m.empty());
return true;
@@ -394,6 +406,7 @@ bool testMap()
bool testMapFilter()
{
Json::Value v(Json::objectValue);
+ cmJSONState state;
v["field1"] = "Hello";
v["field2"] = "world!";
v["ignore"] = "ignore";
@@ -401,15 +414,15 @@ bool testMapFilter()
std::map<std::string, std::string> m{ { "key", "default" } };
std::map<std::string, std::string> expected{ { "field1", "Hello" },
{ "field2", "world!" } };
- ASSERT_TRUE(StringMapFilterHelper(m, &v) == ErrorCode::Success);
+ ASSERT_TRUE(StringMapFilterHelper(m, &v, &state));
ASSERT_TRUE(m == expected);
v = Json::arrayValue;
m = { { "key", "default" } };
- ASSERT_TRUE(StringMapFilterHelper(m, &v) == ErrorCode::InvalidObject);
+ ASSERT_TRUE(!StringMapFilterHelper(m, &v, &state));
m = { { "key", "default" } };
- ASSERT_TRUE(StringMapFilterHelper(m, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(StringMapFilterHelper(m, nullptr, &state));
ASSERT_TRUE(m.empty());
return true;
@@ -418,13 +431,14 @@ bool testMapFilter()
bool testOptional()
{
Json::Value v = "Hello";
+ cmJSONState state;
cm::optional<std::string> str{ "default" };
- ASSERT_TRUE(OptionalStringHelper(str, &v) == ErrorCode::Success);
+ ASSERT_TRUE(OptionalStringHelper(str, &v, &state));
ASSERT_TRUE(str == "Hello");
str.emplace("default");
- ASSERT_TRUE(OptionalStringHelper(str, nullptr) == ErrorCode::Success);
+ ASSERT_TRUE(OptionalStringHelper(str, nullptr, &state));
ASSERT_TRUE(str == cm::nullopt);
return true;
@@ -433,25 +447,24 @@ bool testOptional()
bool testRequired()
{
Json::Value v = "Hello";
-
std::string str = "default";
int i = 1;
- ASSERT_TRUE(RequiredStringHelper(str, &v) == ErrorCode::Success);
+ cmJSONState state;
+ ASSERT_TRUE(RequiredStringHelper(str, &v, &state));
ASSERT_TRUE(str == "Hello");
- ASSERT_TRUE(RequiredIntHelper(i, &v) == ErrorCode::InvalidInt);
+ ASSERT_TRUE(!RequiredIntHelper(i, &v, &state));
v = 2;
str = "default";
i = 1;
- ASSERT_TRUE(RequiredStringHelper(str, &v) == ErrorCode::InvalidString);
- ASSERT_TRUE(RequiredIntHelper(i, &v) == ErrorCode::Success);
+ ASSERT_TRUE(!RequiredStringHelper(str, &v, &state));
+ ASSERT_TRUE(RequiredIntHelper(i, &v, &state));
ASSERT_TRUE(i == 2);
str = "default";
i = 1;
- ASSERT_TRUE(RequiredStringHelper(str, nullptr) ==
- ErrorCode::MissingRequired);
- ASSERT_TRUE(RequiredIntHelper(i, nullptr) == ErrorCode::MissingRequired);
+ ASSERT_TRUE(!RequiredStringHelper(str, nullptr, &state));
+ ASSERT_TRUE(!RequiredIntHelper(i, nullptr, &state));
return true;
}
diff --git a/Tests/RunCMake/CMakePresets/Comment-stderr.txt b/Tests/RunCMake/CMakePresets/Comment-stderr.txt
index b3b6b66d9f..8619cf5fad 100644
--- a/Tests/RunCMake/CMakePresets/Comment-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/Comment-stderr.txt
@@ -1,7 +1,6 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/Comment: JSON parse error
-Errors:
-[^
+]*/Tests/RunCMake/CMakePresets/Comment:
+JSON Parse Error: [^
]*Comment\/CMakePresets.json:
\* Line 1, Column 1
Syntax error: value, object or array expected\.
diff --git a/Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt b/Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt
index ea5f47f653..31ebbc1312 100644
--- a/Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/ConditionFuture: File version must be 3 or higher for condition support$
+]*/Tests/RunCMake/CMakePresets/ConditionFuture:
+File version must be 3 or higher for condition support$
diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt
index 895afcb97c..2d5b477937 100644
--- a/Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/CyclicInheritance0: Cyclic preset inheritance$
+]*/Tests/RunCMake/CMakePresets/CyclicInheritance0:
+Cyclic preset inheritance for preset "CyclicInheritance0"$
diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt
index 1e59e92ed3..596fcf8c17 100644
--- a/Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/CyclicInheritance1: Cyclic preset inheritance$
+]*/Tests/RunCMake/CMakePresets/CyclicInheritance1:
+Cyclic preset inheritance for preset "CyclicInheritance0"$
diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt
index 56e630b526..a6b83c8136 100644
--- a/Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/CyclicInheritance2: Cyclic preset inheritance$
+]*/Tests/RunCMake/CMakePresets/CyclicInheritance2:
+Cyclic preset inheritance for preset "CyclicInheritance0"$
diff --git a/Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt b/Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt
index c9361aea5e..ebb9a2d864 100644
--- a/Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/DuplicatePresets: Duplicate presets$
+]*/Tests/RunCMake/CMakePresets/DuplicatePresets:
+Duplicate preset: "DuplicatePresets"$
diff --git a/Tests/RunCMake/CMakePresets/EmptyCacheKey-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyCacheKey-stderr.txt
index 749d306de6..cb9e545c4a 100644
--- a/Tests/RunCMake/CMakePresets/EmptyCacheKey-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyCacheKey-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EmptyCacheKey: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/EmptyCacheKey:
+Invalid preset: "EmptyCacheKey"$
diff --git a/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt
index 723ac2161b..7774fee8c5 100644
--- a/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EmptyEnv: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/EmptyEnv:
+Invalid macro expansion in "EmptyEnv"$
diff --git a/Tests/RunCMake/CMakePresets/EmptyEnvKey-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyEnvKey-stderr.txt
index 365f537dc3..bc0f8663e7 100644
--- a/Tests/RunCMake/CMakePresets/EmptyEnvKey-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyEnvKey-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EmptyEnvKey: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/EmptyEnvKey:
+Invalid preset: "EmptyEnvKey"$
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt
index 880cee6516..b3bfe21226 100644
--- a/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EmptyPenv: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/EmptyPenv:
+Invalid macro expansion in "EmptyPenv"$
diff --git a/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
index 0d3c5001a1..6f8469022d 100644
--- a/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
@@ -1,5 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EmptyPresetName: Invalid preset
-Errors:
-[^
-]*/EmptyPresetName/CMakePresets.json$
+]*/Tests/RunCMake/CMakePresets/EmptyPresetName:
+Error: @5,15: Invalid Preset Name
+ "name": "",
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt b/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt
index 1d22b87232..8e19c693aa 100644
--- a/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt
@@ -1,2 +1,4 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EnvCycle: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/EnvCycle:
+Invalid preset: "EnvCycle"
+Invalid macro expansion in "EnvCycle"$
diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt
index 3221345498..5c02d5b5e8 100644
--- a/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated:
+Invalid preset: "ErrorNoWarningDeprecated"$
diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt
index d2ddb900de..4640b1ef31 100644
--- a/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/ErrorNoWarningDev: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/ErrorNoWarningDev:
+Invalid preset: "ErrorNoWarningDev"$
diff --git a/Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt b/Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt
index 559e3c2bd2..2e94831c99 100644
--- a/Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/ExtraPresetField: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/ExtraPresetField:
+Error: @8,18: Invalid extra field "invalid" in Preset
+ "invalid": true
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt b/Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt
index bb281beed8..554cd4aa3d 100644
--- a/Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/ExtraRootField: Invalid root object$
+]*/Tests/RunCMake/CMakePresets/ExtraRootField:
+Error: @10,14: Invalid extra field "invalid" in root object
+ "invalid": true
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt b/Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt
index 9b346e78e8..5cb777c42f 100644
--- a/Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/ExtraVariableField: Invalid CMake variable definition$
+]*/Tests/RunCMake/CMakePresets/ExtraVariableField:
+Error: @11,22: Invalid extra field "invalid" in variable "EXTRA" for preset "ExtraVariableField"
+ "invalid": true
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/FileDirFuture-stderr.txt b/Tests/RunCMake/CMakePresets/FileDirFuture-stderr.txt
index ba85f0f42e..b49df79227 100644
--- a/Tests/RunCMake/CMakePresets/FileDirFuture-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/FileDirFuture-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/FileDirFuture: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/FileDirFuture:
+Invalid macro expansion in "FileDirFuture"$
diff --git a/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt
index 36123bdaca..ca481c6a02 100644
--- a/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField: File version must be 3 or higher for installDir preset support.$
+]*/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField:
+File version must be 3 or higher for installDir preset support$
diff --git a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt
index 9382423a35..7aedc6d330 100644
--- a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/FuturePresetToolchainField: File version must be 3 or higher for toolchainFile preset support.$
+]*/Tests/RunCMake/CMakePresets/FuturePresetToolchainField:
+File version must be 3 or higher for toolchainFile preset support$
diff --git a/Tests/RunCMake/CMakePresets/HighVersion-stderr.txt b/Tests/RunCMake/CMakePresets/HighVersion-stderr.txt
index d8622f212e..598478fc66 100644
--- a/Tests/RunCMake/CMakePresets/HighVersion-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/HighVersion-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/HighVersion: Unrecognized "version" field$
+]*/Tests/RunCMake/CMakePresets/HighVersion:
+Error: @2,14: Unrecognized "version" field
+ "version": 1000,
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt b/Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt
index 7f4bb9a243..a1dae4ce72 100644
--- a/Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/HostSystemNameFuture: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/HostSystemNameFuture:
+Invalid macro expansion in "HostSystemNameFuture"$
diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt
index 3343204ca2..fc6292d422 100644
--- a/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt
@@ -1,2 +1,4 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/IncludeCycle: Cyclic include among preset files$
+]*/Tests/RunCMake/CMakePresets/IncludeCycle:
+Cyclic include among preset files: [^
+]*/CMakeUserPresets.json$
diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt
index 35aea4c9ca..1bc402a006 100644
--- a/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt
@@ -1,2 +1,4 @@
-^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/IncludeCycle3Files: Cyclic include among preset files$
+CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/IncludeCycle3Files:
+Cyclic include among preset files: [^
+]*/CMakePresets.json
diff --git a/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
index 85a2d78903..fba5b01b74 100644
--- a/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
@@ -1,5 +1,4 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/IncludeNotFound: File not found
-Errors:
-[^
-]*/IncludeNotFound/NotFound.json: Failed to read file$
+]*/Tests/RunCMake/CMakePresets/IncludeNotFound:
+File not found: [^
+]*/IncludeNotFound/NotFound.json$
diff --git a/Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt
index 1869b6db5f..7e975a7b11 100644
--- a/Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/IncludeV3: File version must be 4 or higher for include support$
+]*/Tests/RunCMake/CMakePresets/IncludeV3:
+File version must be 4 or higher for include support$
diff --git a/Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt
index 89e3e3ddbf..f14c583eea 100644
--- a/Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/IncludeV4V3: File version must be 4 or higher for include support$
+]*/Tests/RunCMake/CMakePresets/IncludeV4V3:
+File version must be 4 or higher for include support$
diff --git a/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt
index 4a4d4ce70c..5df075d789 100644
--- a/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy:
+Error: @9,21: Invalid preset
+ "strategy": {}
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt
index 97f3876737..216f308259 100644
--- a/Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidInheritance: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidInheritance:
+Invalid preset: "InvalidInheritance"$
diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt
index 2fe8c66e93..deb35b46d2 100644
--- a/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir:
+Error: @7,20: "binaryDir" expected a string
+ "binaryDir": \[\]
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt
index 95728752f6..7f194123ff 100644
--- a/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidPresetGenerator: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidPresetGenerator:
+Error: @6,20: "generator" expected a string
+ "generator": \[\],
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt
index 8f6ff7c1d8..4cceb73ad9 100644
--- a/Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidPresetName: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidPresetName:
+Error: @5,15: Invalid Preset Name
+ "name": \[\],
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt
index 89a424ab99..f92c48ec92 100644
--- a/Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidPresetVendor: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidPresetVendor:
+Error: @8,17: Invalid preset
+ "vendor": true
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt
index 2b0f5603e3..d7081afbd8 100644
--- a/Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidPresets: Invalid "configurePresets" field$
+]*/Tests/RunCMake/CMakePresets/InvalidPresets:
+Error: @3,23: Invalid "configurePresets" field
+ "configurePresets": {}
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt
index 5b500e44e8..86cd861729 100644
--- a/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt
@@ -1,2 +1,4 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidRegex: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/InvalidRegex:
+Invalid preset: "InvalidRegex"
+Invalid macro expansion in "InvalidRegex"$
diff --git a/Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt
index e5c434d9bb..5f2dcc1b33 100644
--- a/Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidRoot: Invalid root object$
+]*/Tests/RunCMake/CMakePresets/InvalidRoot:
+Error: \@1\,1\: Invalid root object
+\[\]
+\^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt
index fab3766200..d0974aca81 100644
--- a/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy:
+Error: @9,21: Invalid preset
+ "strategy": {}
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt
index 0ab07c3d0b..fdb7072c87 100644
--- a/Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidVariableValue: Invalid CMake variable definition$
+]*/Tests/RunCMake/CMakePresets/InvalidVariableValue:
+Error: @10,20: "value" expected a string
+ "value": \[\]
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt
index 6d9102a14b..f329d973d1 100644
--- a/Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidVariables: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/InvalidVariables:
+Error: @8,25: Invalid preset
+ "cacheVariables": \[\]
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt
index af923f0ba2..fc6534e2a5 100644
--- a/Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidVendor: Invalid root object$
+]*/Tests/RunCMake/CMakePresets/InvalidVendor:
+Error: @3,13: Invalid root object
+ "vendor": true,
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt
index 7e0fcfdd21..97fe9d6e04 100644
--- a/Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidVersion: Invalid "version" field$
+]*/Tests/RunCMake/CMakePresets/InvalidVersion:
+Error: @2,14: Invalid "version" field
+ "version": "1.0",
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
index 89eff9fc5b..92a1b2b746 100644
--- a/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
@@ -1,9 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/JSONParseError: JSON parse error
-Errors:
-[^
-]*JSONParseError/CMakePresets.json:
-\* Line 1, Column 1
- Syntax error: value, object or array expected\.
-\* Line 1, Column 1
- A valid JSON document must be either an array or an object value\.$
+]*/Tests/RunCMake/CMakePresets/JSONParseError:
+A JSON document cannot be empty
diff --git a/Tests/RunCMake/CMakePresets/LowVersion-stderr.txt b/Tests/RunCMake/CMakePresets/LowVersion-stderr.txt
index 92b3723e1e..e9331006d2 100644
--- a/Tests/RunCMake/CMakePresets/LowVersion-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/LowVersion-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/LowVersion: Unrecognized "version" field$
+]*/Tests/RunCMake/CMakePresets/LowVersion:
+Error: @2,14: Unrecognized "version" field
+ "version": 0,
+ \^
diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt
index 6548cafe21..30ab9ced74 100644
--- a/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid: Invalid "cmakeMinimumRequired" field$
+]*/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid:
+Error: @3,27: Invalid "cmakeMinimumRequired"
+ "cmakeMinimumRequired": "3.18",
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt
index 6036fe3ae3..c9001ea13b 100644
--- a/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/MinimumRequiredMajor: "cmakeMinimumRequired" version too new$
+]*/Tests/RunCMake/CMakePresets/MinimumRequiredMajor:
+Error: @4,14: "cmakeMinimumRequired" major version 1000 must be less than [0-9]*
+ "major": 1000
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt
index bdee4cdeb8..3911c84e84 100644
--- a/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/MinimumRequiredMinor: "cmakeMinimumRequired" version too new$
+]*/Tests/RunCMake/CMakePresets/MinimumRequiredMinor:
+Error: @5,14: "cmakeMinimumRequired" minor version 1000 must be less than [0-9]*
+ "minor": 1000
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt
index b5d3a393f0..e989fa8a7f 100644
--- a/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/MinimumRequiredPatch: "cmakeMinimumRequired" version too new$
+]*/Tests/RunCMake/CMakePresets/MinimumRequiredPatch:
+Error: @6,14: "cmakeMinimumRequired" patch version 50000000 must be less than [0-9]*
+ "patch": 50000000
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt b/Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt
index c807ffc988..afc5887f34 100644
--- a/Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt
@@ -1,2 +1,4 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/NoCMakePresets: File not found$
+]*/Tests/RunCMake/CMakePresets/NoCMakePresets:
+File not found: [^
+]*/CMakePresets.json$
diff --git a/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt
index b525fc322c..bae979473d 100644
--- a/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt
@@ -1,2 +1,4 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/NoPresetBinaryDir: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/NoPresetBinaryDir:
+Preset "NoPresetBinaryDir" missing field "binaryDir"
+Invalid preset: "NoPresetBinaryDir"$
diff --git a/Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt
index 6c0c9f77ab..c7e5b5e23b 100644
--- a/Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt
@@ -1,2 +1,4 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/NoPresetGenerator: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/NoPresetGenerator:
+Preset "NoPresetGenerator" missing field "generator"
+Invalid preset: "NoPresetGenerator"$
diff --git a/Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt
index 0ee338a369..9aff07f45f 100644
--- a/Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/NoPresetName: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/NoPresetName:
+Error: @4,5: Missing required field "name" in Preset
+ {
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt b/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt
index 7dafe623df..8c7ca6e9f8 100644
--- a/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/NoSuchMacro: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/NoSuchMacro:
+Invalid macro expansion in "NoSuchMacro"$
diff --git a/Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt b/Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt
index cdab32f7ba..630c288995 100644
--- a/Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/NoVariableValue: Invalid CMake variable definition$
+]*/Tests/RunCMake/CMakePresets/NoVariableValue:
+Error: @9,16: Missing required field "value" in variable "VAR" for preset "NoVariableValue"
+ "VAR": {}
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/NoVersion-stderr.txt b/Tests/RunCMake/CMakePresets/NoVersion-stderr.txt
index d4f07e499c..f7c95db9fc 100644
--- a/Tests/RunCMake/CMakePresets/NoVersion-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoVersion-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/NoVersion: No "version" field$
+]*/Tests/RunCMake/CMakePresets/NoVersion:
+No "version" field$
diff --git a/Tests/RunCMake/CMakePresets/PathListSepFuture-stderr.txt b/Tests/RunCMake/CMakePresets/PathListSepFuture-stderr.txt
index b961aaf459..7652ddc0e1 100644
--- a/Tests/RunCMake/CMakePresets/PathListSepFuture-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/PathListSepFuture-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/PathListSepFuture: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/PathListSepFuture:
+Invalid macro expansion in "PathListSepFuture"$
diff --git a/Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt b/Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt
index 6604a14c09..62e92485ac 100644
--- a/Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/PresetNotObject: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/PresetNotObject:
+Error: @4,5: Invalid Preset
+ \[\]
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt b/Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt
index 42b74d6177..520b473e6a 100644
--- a/Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/SubConditionNull: Invalid preset condition$
+]*/Tests/RunCMake/CMakePresets/SubConditionNull:
+Invalid condition for preset "SubConditionNull"$
diff --git a/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt b/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt
index f9481f091d..abdbb810c0 100644
--- a/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/UnclosedMacro: Invalid macro expansion$
+]*/Tests/RunCMake/CMakePresets/UnclosedMacro:
+Invalid macro expansion in "UnclosedMacro"$
diff --git a/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt
index cf17881d7a..606376264c 100644
--- a/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy:
+Error: @9,21: Invalid preset
+ "strategy": "unknown"
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt
index 8f9be2998d..55f9c7a779 100644
--- a/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy:
+Error: @9,21: Invalid preset
+ "strategy": "unknown"
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt b/Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt
index 125265f0a6..8b4139ffd9 100644
--- a/Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/UserDuplicateCross: Duplicate presets$
+]*/Tests/RunCMake/CMakePresets/UserDuplicateCross:
+Duplicate preset: "UserDuplicateCross"$
diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt b/Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt
index 1071b1775d..15c46f48fd 100644
--- a/Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/UserDuplicateInUser: Duplicate presets$
+]*/Tests/RunCMake/CMakePresets/UserDuplicateInUser:
+Duplicate preset: "UserDuplicateInUser"$
diff --git a/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt b/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt
index 5ad8b4b6b6..2ce1316413 100644
--- a/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/UserInheritance: Inherited preset is unreachable from preset's file$
+]*/Tests/RunCMake/CMakePresets/UserInheritance:
+Inherited preset "UserInheritance" is unreachable from preset's file$
diff --git a/Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt b/Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt
index 8cacb0a26e..ce1aa20ef7 100644
--- a/Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/VariableNotObject: Invalid CMake variable definition$
+]*/Tests/RunCMake/CMakePresets/VariableNotObject:
+Error: @9,16: Invalid CMake variable "VAR" for preset "VariableNotObject"
+ "VAR": \[\]
+ \^$
diff --git a/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt
index f08f4c11ba..aea1dcebd4 100644
--- a/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsBuild/ConditionFuture: File version must be 3 or higher for condition support$
+]*/Tests/RunCMake/CMakePresetsBuild/ConditionFuture:
+File version must be 3 or higher for condition support$
diff --git a/Tests/RunCMake/CMakePresetsBuild/ConfigurePresetUnreachable-build-x-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/ConfigurePresetUnreachable-build-x-stderr.txt
index 05695d9f75..13b4158dca 100644
--- a/Tests/RunCMake/CMakePresetsBuild/ConfigurePresetUnreachable-build-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsBuild/ConfigurePresetUnreachable-build-x-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsBuild/ConfigurePresetUnreachable: Configure preset is unreachable from preset's file$
+]*/Tests/RunCMake/CMakePresetsBuild/ConfigurePresetUnreachable:
+Configure preset "x" is unreachable from preset's file$
diff --git a/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-build-badConfigurePreset-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-build-badConfigurePreset-stderr.txt
index 303632e54f..b62fd164fa 100644
--- a/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-build-badConfigurePreset-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-build-badConfigurePreset-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset: Invalid "configurePreset" field
+]*/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset:
+Invalid "configurePreset": "badConfigurePreset"$
diff --git a/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-configure-default-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-configure-default-stderr.txt
index 303632e54f..b62fd164fa 100644
--- a/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-configure-default-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset-configure-default-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset: Invalid "configurePreset" field
+]*/Tests/RunCMake/CMakePresetsBuild/InvalidConfigurePreset:
+Invalid "configurePreset": "badConfigurePreset"$
diff --git a/Tests/RunCMake/CMakePresetsBuild/NoConfigurePreset-build-noConfigurePreset-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/NoConfigurePreset-build-noConfigurePreset-stderr.txt
index fcb37bc439..9ce6ea5aad 100644
--- a/Tests/RunCMake/CMakePresetsBuild/NoConfigurePreset-build-noConfigurePreset-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsBuild/NoConfigurePreset-build-noConfigurePreset-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsBuild/NoConfigurePreset: Invalid preset
+]*/Tests/RunCMake/CMakePresetsBuild/NoConfigurePreset:
+Invalid preset: "noConfigurePreset"$
diff --git a/Tests/RunCMake/CMakePresetsBuild/PresetsUnsupported-build-x-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/PresetsUnsupported-build-x-stderr.txt
index d6ae62d6a4..48a5bd39a8 100644
--- a/Tests/RunCMake/CMakePresetsBuild/PresetsUnsupported-build-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsBuild/PresetsUnsupported-build-x-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*Tests/RunCMake/CMakePresetsBuild/PresetsUnsupported: File version must be 2 or higher for build and test preset support.
+]*Tests/RunCMake/CMakePresetsBuild/PresetsUnsupported:
+File version must be 2 or higher for build and test preset support$
diff --git a/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt
index 4c461e3f8b..38ec6bfc53 100644
--- a/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion: File version must be 6 or higher for package preset support$
+]*/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion:
+File version must be 6 or higher for package preset support$
diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt b/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt
index b814bbb94b..3f1a506571 100644
--- a/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsTest/ConditionFuture: File version must be 3 or higher for condition support$
+]*/Tests/RunCMake/CMakePresetsTest/ConditionFuture:
+File version must be 3 or higher for condition support$
diff --git a/Tests/RunCMake/CMakePresetsTest/ConfigurePresetUnreachable-test-x-stderr.txt b/Tests/RunCMake/CMakePresetsTest/ConfigurePresetUnreachable-test-x-stderr.txt
index d49148deb8..0be98efc30 100644
--- a/Tests/RunCMake/CMakePresetsTest/ConfigurePresetUnreachable-test-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/ConfigurePresetUnreachable-test-x-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsTest/ConfigurePresetUnreachable: Configure preset is unreachable from preset's file$
+]*/Tests/RunCMake/CMakePresetsTest/ConfigurePresetUnreachable:
+Configure preset "x" is unreachable from preset's file
diff --git a/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-configure-default-stderr.txt b/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-configure-default-stderr.txt
index 3d7cdd075e..c427e4221b 100644
--- a/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-configure-default-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-configure-default-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset: Invalid "configurePreset" field
+]*/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset:
+Invalid "configurePreset": "badConfigurePreset"$
diff --git a/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-test-badConfigurePreset-stderr.txt b/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-test-badConfigurePreset-stderr.txt
index 3d7cdd075e..c427e4221b 100644
--- a/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-test-badConfigurePreset-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset-test-badConfigurePreset-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset: Invalid "configurePreset" field
+]*/Tests/RunCMake/CMakePresetsTest/InvalidConfigurePreset:
+Invalid "configurePreset": "badConfigurePreset"$
diff --git a/Tests/RunCMake/CMakePresetsTest/NoConfigurePreset-test-noConfigurePreset-stderr.txt b/Tests/RunCMake/CMakePresetsTest/NoConfigurePreset-test-noConfigurePreset-stderr.txt
index b167f68ef6..a70497f295 100644
--- a/Tests/RunCMake/CMakePresetsTest/NoConfigurePreset-test-noConfigurePreset-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/NoConfigurePreset-test-noConfigurePreset-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsTest/NoConfigurePreset: Invalid preset
+]*/Tests/RunCMake/CMakePresetsTest/NoConfigurePreset:
+Invalid preset: "noConfigurePreset"$
diff --git a/Tests/RunCMake/CMakePresetsTest/OutputJUnitUnsupported-test-x-stderr.txt b/Tests/RunCMake/CMakePresetsTest/OutputJUnitUnsupported-test-x-stderr.txt
index acd5785489..da94c3a027 100644
--- a/Tests/RunCMake/CMakePresetsTest/OutputJUnitUnsupported-test-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/OutputJUnitUnsupported-test-x-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsTest/OutputJUnitUnsupported: File version must be 6 or higher for CTest JUnit output support$
+]*/Tests/RunCMake/CMakePresetsTest/OutputJUnitUnsupported:
+File version must be 6 or higher for CTest JUnit output support$
diff --git a/Tests/RunCMake/CMakePresetsTest/PresetsUnsupported-test-x-stderr.txt b/Tests/RunCMake/CMakePresetsTest/PresetsUnsupported-test-x-stderr.txt
index eb0ec1a225..74c0740018 100644
--- a/Tests/RunCMake/CMakePresetsTest/PresetsUnsupported-test-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/PresetsUnsupported-test-x-stderr.txt
@@ -1,2 +1,3 @@
CMake Error: Could not read presets from [^
-]*Tests/RunCMake/CMakePresetsTest/PresetsUnsupported: File version must be 2 or higher for build and test preset support.
+]*Tests/RunCMake/CMakePresetsTest/PresetsUnsupported:
+File version must be 2 or higher for build and test preset support
diff --git a/Tests/RunCMake/CMakePresetsTest/TestOutputTruncationUnsupported-test-x-stderr.txt b/Tests/RunCMake/CMakePresetsTest/TestOutputTruncationUnsupported-test-x-stderr.txt
index 90ea7c3b28..4deb755a9e 100644
--- a/Tests/RunCMake/CMakePresetsTest/TestOutputTruncationUnsupported-test-x-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsTest/TestOutputTruncationUnsupported-test-x-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsTest/TestOutputTruncationUnsupported: File version must be 5 or higher for testOutputTruncation preset support\.$
+]*/Tests/RunCMake/CMakePresetsTest/TestOutputTruncationUnsupported:
+File version must be 5 or higher for testOutputTruncation preset support$
diff --git a/Tests/RunCMake/CMakePresetsWorkflow/ConfigureStepMismatch-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/ConfigureStepMismatch-stderr.txt
index 22ca94d0da..33fe914149 100644
--- a/Tests/RunCMake/CMakePresetsWorkflow/ConfigureStepMismatch-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsWorkflow/ConfigureStepMismatch-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsWorkflow/ConfigureStepMismatch: Invalid workflow steps$
+]*/Tests/RunCMake/CMakePresetsWorkflow/ConfigureStepMismatch:
+Invalid workflow step "default"$
diff --git a/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt
index cbfee5a5c2..776257bd93 100644
--- a/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure: Invalid workflow steps$
+]*/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure:
+First workflow step "default" must be a configure step$
diff --git a/Tests/RunCMake/CMakePresetsWorkflow/NoWorkflowSteps-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/NoWorkflowSteps-stderr.txt
index 049ed6bc51..f34a6053a9 100644
--- a/Tests/RunCMake/CMakePresetsWorkflow/NoWorkflowSteps-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsWorkflow/NoWorkflowSteps-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsWorkflow/NoWorkflowSteps: Invalid workflow steps$
+]*/Tests/RunCMake/CMakePresetsWorkflow/NoWorkflowSteps:
+No workflow steps specified for "default"$
diff --git a/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt
index c522b84d42..a9029e116b 100644
--- a/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep: Invalid workflow steps$
+]*/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep:
+Invalid workflow step "default"$
diff --git a/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt
index b0ad7d530e..35eac16c38 100644
--- a/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure: Invalid workflow steps$
+]*/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure:
+Configure workflow step "default" must be the first step
diff --git a/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt
index 425e7196f0..f0a36f898a 100644
--- a/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep: Workflow step is unreachable from preset's file$
+]*/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep:
+Workflow step "default" is unreachable from preset's file$
diff --git a/Tests/RunCMake/CMakePresetsWorkflow/UnsupportedVersion-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/UnsupportedVersion-stderr.txt
index 5cf01aaa51..93e31eb99d 100644
--- a/Tests/RunCMake/CMakePresetsWorkflow/UnsupportedVersion-stderr.txt
+++ b/Tests/RunCMake/CMakePresetsWorkflow/UnsupportedVersion-stderr.txt
@@ -1,2 +1,3 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresetsWorkflow/UnsupportedVersion: File version must be 6 or higher for workflow preset support$
+]*/Tests/RunCMake/CMakePresetsWorkflow/UnsupportedVersion:
+File version must be 6 or higher for workflow preset support$
diff --git a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
index 5c6c8d87b6..65f17b6e32 100644
--- a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
+++ b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
@@ -286,8 +286,7 @@ static int doVerify(int argc, char const* const* argv)
std::set<std::string> testNameSet(testNameList.begin(), testNameList.end());
cmCTestResourceSpec spec;
- if (spec.ReadFromJSONFile(resFile) !=
- cmCTestResourceSpec::ReadFileResult::READ_OK) {
+ if (spec.ReadFromJSONFile(resFile) != true) {
std::cout << "Could not read resource spec " << resFile << std::endl;
return 1;
}