string(JSON): Add GET_RAW mode

This commit is contained in:
Kyle Edwards
2025-12-16 10:00:29 -05:00
parent 86a2d3e9a5
commit 15973ff247
5 changed files with 48 additions and 10 deletions

View File

@@ -46,7 +46,7 @@ Synopsis
`JSON`_
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
{`GET <JSON-GET_>`__ | `TYPE <JSON-TYPE_>`__ | `LENGTH <JSON-LENGTH_>`__ | `REMOVE <JSON-REMOVE_>`__}
{`GET <JSON-GET_>`__ | `GET_RAW <JSON-GET-RAW_>`__ | `TYPE <JSON-TYPE_>`__ | `LENGTH <JSON-LENGTH_>`__ | `REMOVE <JSON-REMOVE_>`__}
<json-string> <member|index> [<member|index> ...])
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
`MEMBER <JSON-MEMBER_>`__ <json-string>
@@ -559,6 +559,16 @@ string is passed as a single argument even if it contains semicolons.
Null elements will be returned as an empty string.
Number and string types will be returned as strings.
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
GET_RAW <json-string> <member|index> [<member|index> ...])
:target: JSON-GET-RAW
Get an element from ``<json-string>`` at the location given
by the list of ``<member|index>`` arguments. Similar to
`GET <JSON-GET_>`__, but does not convert number, string,
boolean, or null elements.
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
TYPE <json-string> <member|index> [<member|index> ...])

View File

@@ -0,0 +1,4 @@
string-json-improvements
------------------------
* The :command:`string(JSON)` command gained a new ``GET_RAW`` mode.

View File

@@ -952,13 +952,13 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
}
auto const& mode = args.PopFront("missing mode argument"_s);
if (mode != "GET"_s && mode != "TYPE"_s && mode != "MEMBER"_s &&
mode != "LENGTH"_s && mode != "REMOVE"_s && mode != "SET"_s &&
mode != "EQUAL"_s) {
throw json_error(
cmStrCat("got an invalid mode '"_s, mode,
"', expected one of GET, TYPE, MEMBER, LENGTH, REMOVE, SET, "
" EQUAL"_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) {
throw json_error(cmStrCat(
"got an invalid mode '"_s, mode,
"', expected one of GET, GET_RAW, TYPE, MEMBER, LENGTH, REMOVE, SET, "
" EQUAL"_s));
}
auto const& jsonstr = args.PopFront("missing json string argument"_s);
@@ -974,6 +974,10 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
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()));

View File

@@ -65,6 +65,9 @@ set(json1 [=[
"false" : false,
"true" : true
},
"object": {
"foo": "bar"
},
"special" : {
"foo;bar" : "value1",
";" : "value2",
@@ -90,6 +93,7 @@ set(json1 [=[
}
]=])
# test GET
string(JSON result GET "${json1}" foo)
assert_strequal("${result}" bar)
string(JSON result GET "${json1}" array 0)
@@ -200,6 +204,22 @@ string(JSON char ERROR_VARIABLE error GET "${unicode}" datalinkescape)
string(JSON result ERROR_VARIABLE error GET "${unicode}" "${char}")
assert_strequal_error("${result}" "datalinkescape" "${error}")
# Test GET_RAW
string(JSON result GET_RAW "${json1}" values null)
assert_strequal("${result}" null)
string(JSON result GET_RAW "${json1}" values number)
assert_strequal("${result}" 5)
string(JSON result GET_RAW "${json1}" values string)
assert_strequal("${result}" "\"foo\"")
string(JSON result GET_RAW "${json1}" values false)
assert_strequal("${result}" false)
string(JSON result GET_RAW "${json1}" values true)
assert_strequal("${result}" true)
string(JSON result ERROR_VARIABLE error GET_RAW "${json1}" array)
assert_json_equal("${error}" "${result}" [=[ [5, "val", {"some": "other"}, null] ]=])
string(JSON result ERROR_VARIABLE error GET_RAW "${json1}" object)
assert_json_equal("${error}" "${result}" [=[ { "foo": "bar" } ]=])
# Test TYPE
string(JSON result TYPE "${json1}" types null)
assert_strequal("${result}" NULL)
@@ -216,7 +236,7 @@ assert_strequal("${result}" OBJECT)
# Test LENGTH
string(JSON result ERROR_VARIABLE error LENGTH "${json1}")
assert_strequal("${result}" 5)
assert_strequal("${result}" 6)
if(error)
message(SEND_ERROR "Unexpected error: ${error}")
endif()

View File

@@ -1,5 +1,5 @@
CMake Error at JSONWrongMode\.cmake:1 \(string\):
string sub-command JSON got an invalid mode 'FOO', expected one of GET,
TYPE, MEMBER, LENGTH, REMOVE, SET, EQUAL\.
GET_RAW, TYPE, MEMBER, LENGTH, REMOVE, SET, EQUAL\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)