/src/CMake/Source/cmJSONHelpers.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #include "cmConfigure.h" // IWYU pragma: keep |
4 | | |
5 | | #include "cmJSONHelpers.h" |
6 | | |
7 | | #include <functional> |
8 | | #include <string> |
9 | | #include <vector> |
10 | | |
11 | | #include <cm3p/json/value.h> |
12 | | |
13 | | #include "cmJSONState.h" |
14 | | |
15 | | namespace JsonErrors { |
16 | | ErrorGenerator EXPECTED_TYPE(std::string const& type) |
17 | 8 | { |
18 | 8 | return [type](Json::Value const* value, cmJSONState* state) -> void { |
19 | 0 | if (state->key().empty()) { |
20 | 0 | state->AddErrorAtValue(cmStrCat("Expected ", type), value); |
21 | 0 | return; |
22 | 0 | } |
23 | 0 | std::string errMsg = cmStrCat('"', state->key(), "\" expected ", type); |
24 | 0 | if (value && value->isConvertibleTo(Json::ValueType::stringValue)) { |
25 | 0 | errMsg = cmStrCat(errMsg, ", got: ", value->asString()); |
26 | 0 | } |
27 | 0 | state->AddErrorAtValue(errMsg, value); |
28 | 0 | }; |
29 | 8 | } |
30 | | |
31 | | void INVALID_STRING(Json::Value const* value, cmJSONState* state) |
32 | 0 | { |
33 | 0 | JsonErrors::EXPECTED_TYPE("a string")(value, state); |
34 | 0 | } |
35 | | |
36 | | void INVALID_BOOL(Json::Value const* value, cmJSONState* state) |
37 | 0 | { |
38 | 0 | JsonErrors::EXPECTED_TYPE("a bool")(value, state); |
39 | 0 | } |
40 | | |
41 | | void INVALID_INT(Json::Value const* value, cmJSONState* state) |
42 | 0 | { |
43 | 0 | JsonErrors::EXPECTED_TYPE("an integer")(value, state); |
44 | 0 | } |
45 | | |
46 | | void INVALID_UINT(Json::Value const* value, cmJSONState* state) |
47 | 0 | { |
48 | 0 | JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state); |
49 | 0 | } |
50 | | |
51 | | ObjectErrorGenerator INVALID_NAMED_OBJECT( |
52 | | std::function<std::string(Json::Value const*, cmJSONState*)> const& |
53 | | nameGenerator) |
54 | 0 | { |
55 | | #if defined(__GNUC__) && __GNUC__ >= 15 |
56 | | # define CM_GCC_diagnostic_push_Wmaybe_uninitialized |
57 | | # pragma GCC diagnostic push |
58 | | # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" |
59 | | #endif |
60 | 0 | return [nameGenerator]( |
61 | 0 | ObjectError errorType, |
62 | 0 | Json::Value::Members const& extraFields) -> ErrorGenerator { |
63 | 0 | return [nameGenerator, errorType, extraFields]( |
64 | 0 | Json::Value const* value, cmJSONState* state) -> void { |
65 | 0 | std::string name = nameGenerator(value, state); |
66 | 0 | switch (errorType) { |
67 | 0 | case ObjectError::RequiredMissing: |
68 | 0 | state->AddErrorAtValue(cmStrCat("Invalid Required ", name), value); |
69 | 0 | break; |
70 | 0 | case ObjectError::InvalidObject: |
71 | 0 | state->AddErrorAtValue(cmStrCat("Invalid ", name), value); |
72 | 0 | break; |
73 | 0 | case ObjectError::ExtraField: { |
74 | 0 | for (auto const& member : extraFields) { |
75 | 0 | if (value) { |
76 | 0 | state->AddErrorAtValue( |
77 | 0 | cmStrCat("Invalid extra field \"", member, "\" in ", name), |
78 | 0 | &(*value)[member]); |
79 | 0 | } else { |
80 | 0 | state->AddError( |
81 | 0 | cmStrCat("Invalid extra field \"", member, "\" in ", name)); |
82 | 0 | } |
83 | 0 | } |
84 | 0 | } break; |
85 | 0 | case ObjectError::MissingRequired: |
86 | 0 | state->AddErrorAtValue(cmStrCat("Missing required field \"", |
87 | 0 | state->key(), "\" in ", name), |
88 | 0 | value); |
89 | 0 | break; |
90 | 0 | } |
91 | 0 | }; |
92 | 0 | }; |
93 | | #ifdef CM_GCC_diagnostic_push_Wmaybe_uninitialized |
94 | | # pragma GCC diagnostic pop |
95 | | # undef CM_GCC_diagnostic_push_Wmaybe_uninitialized |
96 | | #endif |
97 | 0 | } |
98 | | |
99 | | ErrorGenerator INVALID_OBJECT(ObjectError errorType, |
100 | | Json::Value::Members const& extraFields) |
101 | 0 | { |
102 | 0 | return INVALID_NAMED_OBJECT( |
103 | 0 | [](Json::Value const*, cmJSONState*) -> std::string { return "Object"; })( |
104 | 0 | errorType, extraFields); |
105 | 0 | } |
106 | | |
107 | | ErrorGenerator INVALID_NAMED_OBJECT_KEY( |
108 | | ObjectError errorType, Json::Value::Members const& extraFields) |
109 | 0 | { |
110 | 0 | return INVALID_NAMED_OBJECT( |
111 | 0 | [](Json::Value const*, cmJSONState* state) -> std::string { |
112 | 0 | for (auto it = state->parseStack.rbegin(); |
113 | 0 | it != state->parseStack.rend(); ++it) { |
114 | 0 | if (it->first.rfind("$vector_item_", 0) == 0) { |
115 | 0 | continue; |
116 | 0 | } |
117 | 0 | return cmStrCat('"', it->first, '"'); |
118 | 0 | } |
119 | 0 | return "root"; |
120 | 0 | })(errorType, extraFields); |
121 | 0 | } |
122 | | } |