mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-01-26 19:09:06 +00:00
string(JSON): Add STRING_ENCODE mode
This commit is contained in:
parent
15973ff247
commit
06e6f1e69f
@ -56,6 +56,8 @@ Synopsis
|
||||
<member|index> [<member|index> ...] <value>)
|
||||
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
|
||||
`EQUAL <JSON-EQUAL_>`__ <json-string1> <json-string2>)
|
||||
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
|
||||
`STRING_ENCODE <STRING-ENCODE_>`__ <string>)
|
||||
|
||||
Search and Replace
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
@ -629,3 +631,11 @@ string is passed as a single argument even if it contains semicolons.
|
||||
and ``<json-string2>`` should be valid JSON. The ``<out-var>``
|
||||
will be set to a true value if the JSON objects are considered equal,
|
||||
or a false value otherwise.
|
||||
|
||||
.. signature::
|
||||
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
|
||||
STRING_ENCODE <string>)
|
||||
:target: STRING-ENCODE
|
||||
|
||||
Turn a raw string into a JSON string surrounded by quotes. Special characters
|
||||
will be properly escaped inside the JSON string.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
string-json-improvements
|
||||
------------------------
|
||||
|
||||
* The :command:`string(JSON)` command gained a new ``GET_RAW`` mode.
|
||||
* The :command:`string(JSON)` command gained new ``GET_RAW`` and ``STRING_ENCODE`` modes.
|
||||
|
||||
@ -954,113 +954,120 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
|
||||
auto const& mode = args.PopFront("missing mode argument"_s);
|
||||
if (mode != "GET"_s && mode != "GET_RAW"_s && mode != "TYPE"_s &&
|
||||
mode != "MEMBER"_s && mode != "LENGTH"_s && mode != "REMOVE"_s &&
|
||||
mode != "SET"_s && mode != "EQUAL"_s) {
|
||||
mode != "SET"_s && mode != "EQUAL"_s && mode != "STRING_ENCODE"_s) {
|
||||
throw json_error(cmStrCat(
|
||||
"got an invalid mode '"_s, mode,
|
||||
"', expected one of GET, GET_RAW, TYPE, MEMBER, LENGTH, REMOVE, SET, "
|
||||
" EQUAL"_s));
|
||||
" EQUAL, STRING_ENCODE"_s));
|
||||
}
|
||||
|
||||
auto const& jsonstr = args.PopFront("missing json string argument"_s);
|
||||
Json::Value json = ReadJson(jsonstr);
|
||||
|
||||
if (mode == "GET"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
if (value.isObject() || value.isArray()) {
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(value));
|
||||
} else if (value.isBool()) {
|
||||
makefile.AddDefinitionBool(*outputVariable, value.asBool());
|
||||
} else {
|
||||
makefile.AddDefinition(*outputVariable, value.asString());
|
||||
}
|
||||
|
||||
} else if (mode == "GET_RAW"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(value));
|
||||
|
||||
} else if (mode == "TYPE"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
makefile.AddDefinition(*outputVariable, JsonTypeToString(value.type()));
|
||||
|
||||
} else if (mode == "MEMBER"_s) {
|
||||
auto const& indexStr = args.PopBack("missing member index"_s);
|
||||
auto const& value = ResolvePath(json, args);
|
||||
if (!value.isObject()) {
|
||||
throw json_error(
|
||||
cmStrCat("MEMBER needs to be called with an element of "
|
||||
"type OBJECT, got "_s,
|
||||
JsonTypeToString(value.type())),
|
||||
args);
|
||||
}
|
||||
auto const index = ParseIndex(
|
||||
indexStr, Args{ args.begin(), args.end() + 1 }, value.size());
|
||||
auto const memIt = std::next(value.begin(), index);
|
||||
makefile.AddDefinition(*outputVariable, memIt.name());
|
||||
|
||||
} else if (mode == "LENGTH"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
if (!value.isArray() && !value.isObject()) {
|
||||
throw json_error(cmStrCat("LENGTH needs to be called with an "
|
||||
"element of type ARRAY or OBJECT, got "_s,
|
||||
JsonTypeToString(value.type())),
|
||||
args);
|
||||
}
|
||||
|
||||
cmAlphaNum sizeStr{ value.size() };
|
||||
makefile.AddDefinition(*outputVariable, sizeStr.View());
|
||||
|
||||
} else if (mode == "REMOVE"_s) {
|
||||
auto const& toRemove =
|
||||
args.PopBack("missing member or index to remove"_s);
|
||||
auto& value = ResolvePath(json, args);
|
||||
|
||||
if (value.isArray()) {
|
||||
auto const index = ParseIndex(
|
||||
toRemove, Args{ args.begin(), args.end() + 1 }, value.size());
|
||||
Json::Value removed;
|
||||
value.removeIndex(index, &removed);
|
||||
|
||||
} else if (value.isObject()) {
|
||||
Json::Value removed;
|
||||
value.removeMember(toRemove, &removed);
|
||||
|
||||
} else {
|
||||
throw json_error(cmStrCat("REMOVE needs to be called with an "
|
||||
"element of type ARRAY or OBJECT, got "_s,
|
||||
JsonTypeToString(value.type())),
|
||||
args);
|
||||
}
|
||||
if (mode == "STRING_ENCODE"_s) {
|
||||
Json::Value json(jsonstr);
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(json));
|
||||
} else {
|
||||
Json::Value json = ReadJson(jsonstr);
|
||||
|
||||
} else if (mode == "SET"_s) {
|
||||
auto const& newValueStr = args.PopBack("missing new value remove"_s);
|
||||
auto const& toAdd = args.PopBack("missing member name to add"_s);
|
||||
auto& value = ResolvePath(json, args);
|
||||
|
||||
Json::Value newValue = ReadJson(newValueStr);
|
||||
if (value.isObject()) {
|
||||
value[toAdd] = newValue;
|
||||
} else if (value.isArray()) {
|
||||
auto const index =
|
||||
ParseIndex(toAdd, Args{ args.begin(), args.end() + 1 });
|
||||
if (value.isValidIndex(index)) {
|
||||
value[static_cast<int>(index)] = newValue;
|
||||
if (mode == "GET"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
if (value.isObject() || value.isArray()) {
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(value));
|
||||
} else if (value.isBool()) {
|
||||
makefile.AddDefinitionBool(*outputVariable, value.asBool());
|
||||
} else {
|
||||
value.append(newValue);
|
||||
makefile.AddDefinition(*outputVariable, value.asString());
|
||||
}
|
||||
} else {
|
||||
throw json_error(cmStrCat("SET needs to be called with an "
|
||||
"element of type OBJECT or ARRAY, got "_s,
|
||||
JsonTypeToString(value.type())));
|
||||
|
||||
} else if (mode == "GET_RAW"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(value));
|
||||
|
||||
} else if (mode == "TYPE"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
makefile.AddDefinition(*outputVariable,
|
||||
JsonTypeToString(value.type()));
|
||||
|
||||
} else if (mode == "MEMBER"_s) {
|
||||
auto const& indexStr = args.PopBack("missing member index"_s);
|
||||
auto const& value = ResolvePath(json, args);
|
||||
if (!value.isObject()) {
|
||||
throw json_error(
|
||||
cmStrCat("MEMBER needs to be called with an element of "
|
||||
"type OBJECT, got "_s,
|
||||
JsonTypeToString(value.type())),
|
||||
args);
|
||||
}
|
||||
auto const index = ParseIndex(
|
||||
indexStr, Args{ args.begin(), args.end() + 1 }, value.size());
|
||||
auto const memIt = std::next(value.begin(), index);
|
||||
makefile.AddDefinition(*outputVariable, memIt.name());
|
||||
|
||||
} else if (mode == "LENGTH"_s) {
|
||||
auto const& value = ResolvePath(json, args);
|
||||
if (!value.isArray() && !value.isObject()) {
|
||||
throw json_error(cmStrCat("LENGTH needs to be called with an "
|
||||
"element of type ARRAY or OBJECT, got "_s,
|
||||
JsonTypeToString(value.type())),
|
||||
args);
|
||||
}
|
||||
|
||||
cmAlphaNum sizeStr{ value.size() };
|
||||
makefile.AddDefinition(*outputVariable, sizeStr.View());
|
||||
|
||||
} else if (mode == "REMOVE"_s) {
|
||||
auto const& toRemove =
|
||||
args.PopBack("missing member or index to remove"_s);
|
||||
auto& value = ResolvePath(json, args);
|
||||
|
||||
if (value.isArray()) {
|
||||
auto const index = ParseIndex(
|
||||
toRemove, Args{ args.begin(), args.end() + 1 }, value.size());
|
||||
Json::Value removed;
|
||||
value.removeIndex(index, &removed);
|
||||
|
||||
} else if (value.isObject()) {
|
||||
Json::Value removed;
|
||||
value.removeMember(toRemove, &removed);
|
||||
|
||||
} else {
|
||||
throw json_error(cmStrCat("REMOVE needs to be called with an "
|
||||
"element of type ARRAY or OBJECT, got "_s,
|
||||
JsonTypeToString(value.type())),
|
||||
args);
|
||||
}
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(json));
|
||||
|
||||
} else if (mode == "SET"_s) {
|
||||
auto const& newValueStr = args.PopBack("missing new value remove"_s);
|
||||
auto const& toAdd = args.PopBack("missing member name to add"_s);
|
||||
auto& value = ResolvePath(json, args);
|
||||
|
||||
Json::Value newValue = ReadJson(newValueStr);
|
||||
if (value.isObject()) {
|
||||
value[toAdd] = newValue;
|
||||
} else if (value.isArray()) {
|
||||
auto const index =
|
||||
ParseIndex(toAdd, Args{ args.begin(), args.end() + 1 });
|
||||
if (value.isValidIndex(index)) {
|
||||
value[static_cast<int>(index)] = newValue;
|
||||
} else {
|
||||
value.append(newValue);
|
||||
}
|
||||
} else {
|
||||
throw json_error(cmStrCat("SET needs to be called with an "
|
||||
"element of type OBJECT or ARRAY, got "_s,
|
||||
JsonTypeToString(value.type())));
|
||||
}
|
||||
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(json));
|
||||
|
||||
} else if (mode == "EQUAL"_s) {
|
||||
auto const& jsonstr2 =
|
||||
args.PopFront("missing second json string argument"_s);
|
||||
Json::Value json2 = ReadJson(jsonstr2);
|
||||
makefile.AddDefinitionBool(*outputVariable, json == json2);
|
||||
}
|
||||
|
||||
makefile.AddDefinition(*outputVariable, WriteJson(json));
|
||||
|
||||
} else if (mode == "EQUAL"_s) {
|
||||
auto const& jsonstr2 =
|
||||
args.PopFront("missing second json string argument"_s);
|
||||
Json::Value json2 = ReadJson(jsonstr2);
|
||||
makefile.AddDefinitionBool(*outputVariable, json == json2);
|
||||
}
|
||||
|
||||
} catch (json_error const& e) {
|
||||
|
||||
@ -360,3 +360,19 @@ assert_json_equal("${error}" "${result}"
|
||||
"foo" : "bar",
|
||||
"array" : [5, "val", {"some": "other"}, null, "append"]
|
||||
}]=])
|
||||
|
||||
# Test STRING_ENCODE
|
||||
string(JSON result STRING_ENCODE Hello)
|
||||
assert_strequal("${result}" "\"Hello\"")
|
||||
string(JSON result STRING_ENCODE "\"Hello\"")
|
||||
assert_strequal("${result}" "\"\\\"Hello\\\"\"")
|
||||
string(JSON result STRING_ENCODE null)
|
||||
assert_strequal("${result}" "\"null\"")
|
||||
string(JSON result STRING_ENCODE 0)
|
||||
assert_strequal("${result}" "\"0\"")
|
||||
string(JSON result STRING_ENCODE false)
|
||||
assert_strequal("${result}" "\"false\"")
|
||||
string(JSON result STRING_ENCODE {})
|
||||
assert_strequal("${result}" "\"{}\"")
|
||||
string(JSON result STRING_ENCODE [])
|
||||
assert_strequal("${result}" "\"[]\"")
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
CMake Error at JSONWrongMode\.cmake:1 \(string\):
|
||||
string sub-command JSON got an invalid mode 'FOO', expected one of GET,
|
||||
GET_RAW, TYPE, MEMBER, LENGTH, REMOVE, SET, EQUAL\.
|
||||
GET_RAW, TYPE, MEMBER, LENGTH, REMOVE, SET, EQUAL, STRING_ENCODE\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user